做不出题就来打一场模拟赛吧!
http://codeforces.com/contest/740
A. Alyona and copybooks
水,直接暴力for吧,特判容易被HACK
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 10010 10 #define llg long long 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,a,b,c,ans; 13 int main() 14 { 15 // yyj("A"); 16 cin>>n>>a>>b>>c; 17 ans=(llg)1e18; 18 for (llg x=0;x<=10;x++) 19 for (llg y=0;y<=10;y++) 20 for (llg z=0;z<=10;z++) 21 { 22 if ((n+x+y*2+z*3)%4==0) ans=min(ans,a*x+b*y+c*z); 23 } 24 cout<<ans; 25 return 0; 26 }
B. Alyona and flowers
水。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 10010 10 #define llg int 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,l,r,ans,a[maxn]; 13 int main() 14 { 15 //yyj("B"); 16 cin>>n>>m; 17 for (llg i=1;i<=n;i++) scanf("%d",&a[i]); 18 while (m--) 19 { 20 cin>>l>>r; 21 llg x=0; 22 for (llg i=l;i<=r;i++) x+=a[i]; 23 ans+=max(0,x); 24 } 25 cout<<ans; 26 return 0; 27 }
C. Alyona and mex
这就有点厉害了,考虑答案一定是最小的那个区间的大小,然后大力构造一番就可以了。
但是,想想啊,既然我知道了答案是多少,那直接0,1,2,...,ans-1,0,1,2.....,ans-1,这样构造不就可以了么。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 #include<queue> 9 using namespace std; 10 #define maxn 1001000 11 #define llg int 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,m,l,r,mid,bj[maxn]; 14 15 queue<llg>dl; 16 17 struct node 18 { 19 llg l,r; 20 }ask[maxn]; 21 22 llg ans,a[maxn]; 23 24 bool cmp(const node&a,const node&b) 25 { 26 if (a.l==b.l) return a.r<b.r; 27 else return a.l<b.l; 28 } 29 30 31 int main() 32 { 33 //yyj("C"); 34 cin>>n>>m; 35 ans=0x7fffffff; 36 for (llg i=1;i<=m;i++) 37 { 38 scanf("%d%d",&ask[i].l,&ask[i].r); 39 ans=min(ask[i].r-ask[i].l+1,ans); 40 } 41 sort(ask+1,ask+m+1,cmp); 42 llg lax=0,cnt=0; 43 llg be=0; 44 for (llg i=0;i<ans;i++) dl.push(i); 45 for (llg i=1;i<=m;i++) 46 { 47 l=ask[i].l,r=ask[i].r; 48 be=max(l-1,be); 49 if (l==ask[i-1].l) continue; 50 for (llg j=lax;j<l;j++) 51 if (bj[a[j]]) 52 { 53 cnt++; 54 bj[a[j]]=0; 55 dl.push(a[j]); 56 } 57 for (llg j=be+1;j<=r;j++) 58 { 59 if (dl.empty()) break; 60 be=max(j,be); 61 llg x=dl.front(); 62 dl.pop(); 63 a[j]=x; 64 bj[x]=1; 65 } 66 lax=l; 67 } 68 cout<<ans<<endl; 69 for (llg i=1;i<=n;i++) printf("%d ",a[i]); 70 return 0; 71 }
D. Alyona and a tree
倍增找出树上每一个点对应的可以影响到它到哪一个祖先节点,对于这一条路径上所有点的权值+1,树链剖分维护一下即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 1200100 10 #define llg long long 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,deep[maxn],sum[maxn],addv[maxn],top[maxn],re[maxn],pos[maxn],size[maxn],sz; 13 llg dad[maxn]; 14 vector<llg>a[maxn],val[maxn]; 15 llg f[maxn/4][21],dis[maxn/4][21],d[maxn]; 16 17 void pushdown(llg o,llg l,llg r) 18 { 19 if (!addv[o]) return ; 20 llg lc=o<<1,rc=lc+1,mid=(l+r)>>1; 21 addv[lc]+=addv[o],addv[rc]+=addv[o]; 22 sum[lc]+=addv[o]*(mid-l+1); sum[rc]+=addv[o]*(r-mid); 23 addv[o]=0; 24 } 25 26 void add(llg o,llg l,llg r,llg L,llg R,llg vv) 27 { 28 pushdown(o,l,r); 29 if (l>=L && r<=R) 30 { 31 addv[o]+=vv; sum[o]+=vv*(r-l+1); 32 return ; 33 } 34 llg lc=o<<1,rc=lc+1,mid=(l+r)>>1; 35 if (L<=mid) add(lc,l,mid,L,R,vv); 36 if (R>mid) add(rc,mid+1,r,L,R,vv); 37 sum[o]=sum[lc]+sum[rc]; 38 } 39 40 void sloveadd(llg x,llg y,llg vv) 41 { 42 while (top[x]!=top[y]) 43 { 44 if (deep[top[x]]<deep[top[y]]) swap(x,y); 45 add(1,1,n,pos[top[x]],pos[x],vv); 46 x=dad[top[x]]; 47 } 48 if (pos[x]>pos[y]) swap(x,y); 49 add(1,1,n,pos[x],pos[y],vv); 50 } 51 52 void dfs1(llg x,llg fa) 53 { 54 llg w=a[x].size(); 55 size[x]=1; 56 for (llg i=0;i<w;i++) 57 { 58 llg v=a[x][i]; 59 if (v==fa) continue; 60 deep[v]=deep[x]+1; 61 dad[v]=x; 62 dfs1(v,x); 63 size[x]+=size[v]; 64 } 65 } 66 67 llg ask_quan(llg o,llg l,llg r,llg L,llg R) 68 { 69 pushdown(o,l,r); 70 if (l>=L && r<=R) 71 { 72 return sum[o]; 73 } 74 llg lc=o<<1,rc=lc+1,mid=(l+r)>>1,ans; 75 if (L<=mid) ans=ask_quan(lc,l,mid,L,R); 76 if (R>mid) ans=ask_quan(rc,mid+1,r,L,R); 77 sum[o]=sum[lc]+sum[rc]; 78 return ans; 79 } 80 81 void dfs2(llg x,llg chain) 82 { 83 llg k=0,w=a[x].size(); sz++; 84 pos[x]=re[x]=sz; top[x]=chain; 85 for (llg i=0;i<w;i++) 86 { 87 llg v=a[x][i]; 88 if (deep[v]>deep[x] && size[v]>size[k]) k=v; 89 } 90 if (k==0) return ; 91 dfs2(k,chain); 92 for (llg i=0;i<w;i++) 93 { 94 llg v=a[x][i]; 95 if (deep[v]>deep[x] && k!=v) dfs2(v,v); 96 } 97 re[x]=sz; 98 } 99 100 void make_f() 101 { 102 for (llg i=0;i<=20;i++) dis[1][i]=dis[0][i]=(llg)1e16; 103 for (llg j=1;j<=20;j++) 104 for (llg i=1;i<=n;i++) 105 { 106 f[i][j]=f[f[i][j-1]][j-1]; 107 dis[i][j]=dis[i][j-1]+dis[f[i][j-1]][j-1]; 108 } 109 } 110 111 void init() 112 { 113 cin>>n; 114 llg x,y; 115 for (llg i=1;i<=n;i++) scanf("%I64d",&d[i]); 116 for (llg i=2;i<=n;i++) 117 { 118 scanf("%I64d%I64d",&x,&y); 119 a[x].push_back(i),dad[i]=x; 120 dis[i][0]=y; f[i][0]=x; 121 } 122 make_f(); 123 } 124 125 llg find_(llg x,llg res) 126 { 127 if (dis[x][0]>res || x==1) return -1; 128 for (llg i=20;i>=0;i--) 129 if (dis[x][i]<=res) 130 { 131 res-=dis[x][i]; 132 x=f[x][i]; 133 } 134 return x; 135 } 136 137 int main() 138 { 139 // yyj("D"); 140 init(); 141 dfs1(1,-1); 142 dfs2(1,1); 143 for (llg i=2;i<=n;i++) 144 { 145 llg x=find_(i,d[i]); 146 if (x==-1) continue; 147 sloveadd(f[i][0],x,1); 148 } 149 for (llg i=1;i<=n;i++) printf("%I64d ",ask_quan(1,1,n,pos[i],pos[i])); 150 return 0; 151 }
E. Alyona and towers
将数组差分,然后用线段树支持区间查询,合并的时候注意一下细节。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 3000005 10 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 11 using namespace std; 12 #define llg long long 13 struct node 14 { 15 llg l,m,r; 16 }po[maxn]; 17 18 llg arr[maxn],n,m,a[maxn]; 19 20 llg sign(llg x) 21 { 22 if (x>0) return 1; 23 if (x<0) return -1; 24 return 0; 25 } 26 27 void add(llg x,llg l,llg r) 28 { 29 llg m=(l+r)/2; 30 po[x].m=max(po[x*2].m,po[x*2+1].m); 31 po[x].l=po[x*2].l; 32 po[x].r=po[x*2+1].r; 33 if (!!a[m] && !!a[m+1] && sign(a[m])>=sign(a[m+1])) 34 { 35 po[x].m=max(po[x].m,po[x*2].r+po[x*2+1].l); 36 if(po[2*x].m==m-l+1) po[x].l=po[2*x].l+po[2*x+1].l; 37 if(po[2*x+1].m==r-m) po[x].r=po[2*x].r+po[2*x+1].r; 38 } 39 } 40 41 void build(llg x,llg l,llg r) 42 { 43 if (l==r) 44 { 45 llg tmp=!!a[l]; 46 po[x]={tmp,tmp,tmp}; 47 return; 48 } 49 llg m=(l+r)/2; 50 build(x*2,l,m); 51 build(x*2+1,m+1,r); 52 add(x,l,r); 53 } 54 void update(llg x,llg l,llg r,llg pos,llg d) 55 { 56 if(l==r) 57 { 58 a[pos]+=d; 59 llg tmp=!!a[pos]; 60 po[x]={tmp,tmp,tmp}; 61 return; 62 } 63 llg m=(l+r)/2; 64 if(pos<=m) update(x*2,l,m,pos,d);else update(x*2+1,m+1,r,pos,d); 65 add(x,l,r); 66 } 67 68 int main() 69 { 70 // yyj("E"); 71 cin>>n; 72 for (llg i=0;i<n;i++) scanf("%I64d",&arr[i]); 73 for (llg i=0;i+1<n;i++) a[i]=arr[i+1]-arr[i]; 74 if (n>1) build(1,0,n-2); 75 cin>>m; 76 while (m--) 77 { 78 llg l,r,d; 79 scanf("%I64d%I64d%I64d",&l,&r,&d); 80 if (n==1) 81 { 82 printf("%I64d ",(llg)1); 83 continue; 84 } 85 if (l>1) update(1,0,n-2,l-2,d); 86 if (r<n) update(1,0,n-2,r-1,-d); 87 printf("%I64d ",po[1].m+1); 88 } 89 return 0; 90 }