博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
usaco 2017 January Platinum
阅读量:5286 次
发布时间:2019-06-14

本文共 3949 字,大约阅读时间需要 13 分钟。

1.Promotion Counting

给定一棵树,每个点一个权值,求每个点权值比他大的子孙的个数。n<=10^5

题解:离散一下线段树维护。dfs到每个点的时候求一个答案,dfs完它的子孙求一个答案,求差即可。

#include
#include
#include
#define N 131072#define MAXN 100000using namespace std;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;} int s[MAXN+5];struct edge{ int to,next;}e[MAXN+5];int num[MAXN+5];int head[MAXN+5];int n,cnt=0;int T[N*2+5];int ans[MAXN+5]; void renew(int x,int ad){ T[x+=N]+=ad; for(x>>=1;x;x>>=1) T[x]=T[x<<1]+T[(x<<1)+1];} int query(int l,int r){ int sum=0; for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1) { if(~l&1) sum+=T[l+1]; if( r&1) sum+=T[r-1]; } return sum;} inline void ins(int f,int t){ e[++cnt].next=head[f]; head[f]=cnt; e[cnt].to=t;} void dfs(int x){ renew(num[x],1); ans[x]=-query(num[x],n); for(int i=head[x];i>0;i=e[i].next) {dfs(e[i].to);} ans[x]+=query(num[x],n);} int main(){ n=read(); for(int i=1;i<=n;i++) s[i]=num[i]=read(); sort(s+1,s+n+1); int j=0; for(int i=1;i<=n;i++) if(s[i]!=s[i-1]) s[++j]=s[i]; for(int i=1;i<=n;i++) num[i]=lower_bound(s+1,s+j+1,num[i])-s; for(int i=1;i

2.Building a Tall Barn

题目大意:给定长度为N的序列ai,对每个ai分配ci使得ci>0(ci为整数)且ci之和等于K,求出最小的ai/ci之和。

题解:二分每个数最后一次减少了多少(对于一个数,如果已经分到了2,再加1的时候它就减少1/6)

然后对每个数求二元一次方程。  A/n(n+1)=B

复杂度nlogn

#include
#include
#include
#include
#include
#define INF 100000000000000LL#define eps 1e-13using namespace std;#define ll long longll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;} int n;ll K;ll ans=INF;double a[100005]; ll cal(double x){
return (ll)((sqrt(1+4*x)-1)/2);} bool check(double x){ ll left=K; for(int i=1;i<=n;i++) { if(a[i]<=x) continue; ll xx=cal(a[i]/x); left-=xx; } //cout<
<<" "<
<

3.Subsequence Reversal

给定一个长度为N的序列,允许翻转一个子序列,求最长不下降子序列长度。n和数字都<=50

用f[i][j][k][l]表示i-j的区间内只用k-l的数的最大不下降子序列长度。

然后两端的数换不换都转移一下。

复杂度 n^4

#include
#include
#include
#define MAXN 50using namespace std;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;} int n,maxn=0;int s[MAXN+5];int f[MAXN+5][MAXN+5][MAXN+5][MAXN+5]; int main(){ n=read(); for(int i=1;i<=n;++i)s[i]=read(); for(int l=1;l<=n;l++) { for(int i=1;i+l-1<=n;i++) { int j=i+l-1; for(int x=50;x>=1;x--) for(int y=x;y<=50;y++) { f[i][j][x][y]=max(f[i][j][x+1][y],f[i][j][x][y-1]); f[i][j][x][y]=max(f[i][j][x][y],f[i+1][j][x][y]); f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x][y]); if(s[j]<=s[i]&&x<=s[j]&&y>=s[i]&&l!=1)                     f[i][j][x][y]=max(f[i][j][x][y],f[i+1][j-1][s[j]][s[i]]+2); if(s[i]>=x&&y>=s[i]) f[i][j][x][y]=max(f[i][j][x][y],f[i+1][j-1][x][s[i]]+1); if(x<=s[j]&&s[j]<=y) f[i][j][x][y]=max(f[i][j][x][y],f[i+1][j-1][s[j]][y]+1); if(x<=s[i]&&s[i]<=y) f[i][j][x][y]=max(f[i][j][x][y],f[i+1][j][s[i]][y]+1); if(y>=s[j]&&s[j]>=x) f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x][s[j]]+1); // printf("%d %d %d %d %d\n",i,j,x,y,f[i][j][x][y]); } } } printf("%d\n",f[1][n][1][50]); return 0;}

 

转载于:https://www.cnblogs.com/FallDream/p/usaco2017Jan.html

你可能感兴趣的文章
JPA与Spring2.5整合时发生不能创建entityManagerFactory的问题解决方法
查看>>
FastDFS 初始
查看>>
选项卡
查看>>
14-----定时器
查看>>
XidianOJ 1028 数字工程
查看>>
派遣函数
查看>>
教程6--配置ssh
查看>>
C#串口扫描枪的简单实现
查看>>
SharePoint各版本信息
查看>>
Python数据结构——散列表
查看>>
.Net学习笔记----2015-07-08(基础复习和练习03)
查看>>
IDEA 中Spark SQL通过JDBC连接mysql数据库
查看>>
组合数学之母函数问题
查看>>
JavaScript创建对象之单例、工厂、构造函数模式
查看>>
CodeForces1154F
查看>>
TLS 9.2C
查看>>
CodeForces1214A
查看>>
LuoGuP4551最长异或路径
查看>>
CodeForces1214C
查看>>
CodeForces1214B
查看>>