codeforces 739A
答案一定是所有区间中最小区间长度,构造的话就把所有区间都当成那个长度即可

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int b[100010]; 5 struct node{int x,y;} a[100010]; 6 int n,m; 7 8 bool cmp(node a,node b) 9 { 10 return a.x<b.x; 11 } 12 13 int main() 14 { 15 scanf("%d%d",&n,&m); 16 int ans=n; 17 for (int i=1; i<=m; i++) 18 { 19 scanf("%d%d",&a[i].x,&a[i].y); 20 ans=min(ans,a[i].y-a[i].x+1); 21 } 22 sort(a+1,a+1+m,cmp); 23 for (int i=1; i<=m; i++) 24 a[i].y=a[i].x+ans-1; 25 printf("%d ",ans); 26 for (int i=1; i<=m; i++) 27 { 28 if (a[i].x==a[i-1].x) continue; 29 if (a[i].x>a[i-1].y) 30 { 31 for (int j=0; j<ans; j++) 32 b[a[i].x+j]=j; 33 } 34 else { 35 int k=a[i-1].y+1; 36 for (int j=a[i-1].x; j<=a[i].x; j++) 37 b[k++]=b[j]; 38 } 39 } 40 for (int i=1; i<=n; i++) printf("%d ",b[i]); 41 }
codeforces 739B
做法很多,可以树上差分统计然后二分点到根这段,也可以直接用可持久化线段树维护

1 #include<bits/stdc++.h> 2 #define mp make_pair 3 using namespace std; 4 typedef long long ll; 5 struct way{int po,next,len;} e[200010]; 6 int ans[200010],p[200010],a[200010]; 7 ll d[200010]; 8 vector< pair<ll,int> > st; 9 int n,len; 10 11 void add(int x,int y,int z) 12 { 13 e[++len].po=y; 14 e[len].next=p[x]; 15 e[len].len=z; 16 p[x]=len; 17 } 18 19 void dfs(int x) 20 { 21 st.push_back(mp(d[x],x)); 22 int j=lower_bound(st.begin(),st.end(),mp(d[x]-a[x],0))-st.begin()-1; 23 if (j>=0) ans[st[j].second]--; 24 for (int i=p[x]; i; i=e[i].next) 25 { 26 int y=e[i].po; 27 d[y]=d[x]+e[i].len; 28 dfs(y); 29 ans[x]+=ans[y]+1; 30 } 31 st.pop_back(); 32 } 33 34 int main() 35 { 36 scanf("%d",&n); 37 for (int i=1; i<=n; i++) scanf("%d",&a[i]); 38 for (int i=2; i<=n; i++) 39 { 40 int x,y; 41 scanf("%d%d",&x,&y); 42 add(x,i,y); 43 } 44 dfs(1); 45 for (int i=1; i<=n; i++) printf("%d ",ans[i]); 46 }
hdu5071
vector大模拟

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define mp make_pair 5 6 typedef long long ll; 7 typedef pair<int,ll> pi; 8 vector<pi> p; 9 int x,now; 10 11 int get(int x) 12 { 13 for (int i=0; i<p.size(); i++) 14 if (p[i].first==x) return i; 15 return -1; 16 } 17 18 void erase(int x) 19 { 20 int i=0; 21 for( vector<pi>::iterator it=p.begin();it!=p.end(); it++,i++){ 22 if (i==x) 23 { 24 p.erase(it); 25 return; 26 } 27 } 28 } 29 30 void add() 31 { 32 scanf("%d",&x); 33 if (get(x)!=-1) puts("same priority."); 34 else { 35 p.push_back(mp(x,0)); 36 puts("success."); 37 } 38 } 39 40 void close() 41 { 42 scanf("%d",&x); 43 int k=get(x); 44 if (k==-1) puts("invalid priority."); 45 else{ 46 if(x==now) now=0; 47 printf("close %d with %I64d. ",p[k].first,p[k].second); 48 erase(k); 49 } 50 } 51 void chat() 52 { 53 scanf("%d",&x); 54 if (!p.size()) puts("empty."); 55 else { 56 if (now) p[get(now)].second+=x; 57 else p[0].second+=x; 58 puts("success."); 59 } 60 } 61 62 void rot(int y) 63 { 64 if (y<1||y>p.size()) puts("out of range."); 65 else{ 66 pi pp=p[y-1]; 67 erase(y-1); 68 p.insert(p.begin(),pp); 69 puts("success."); 70 } 71 } 72 73 void prior() 74 { 75 int mx=0,k=-1; 76 if (!p.size()) puts("empty."); 77 else { 78 for(int i=0;i<p.size();++i) 79 if(p[i].first>mx) {mx=p[i].first;k=i;} 80 rot(k+1); 81 } 82 } 83 void choose() 84 { 85 scanf("%d",&x); 86 int ch=get(x); 87 if (ch==-1) puts("invalid priority."); 88 else rot(ch+1); 89 } 90 91 void top() 92 { 93 scanf("%d",&x); 94 if(get(x)==-1) puts("invalid priority."); 95 else now=x,puts("success."); 96 } 97 void untop() 98 { 99 if (now) {now=0;puts("success.");} 100 else puts("no such person."); 101 } 102 103 void bye() 104 { 105 if (now) 106 { 107 x=get(now); 108 if(p[x].second!=0) printf("Bye %d: %I64d ",p[x].first,p[x].second); 109 erase(x); 110 } 111 for (int i=0; i<p.size(); i++) 112 if (p[i].second) printf("Bye %d: %I64d ",p[i].first,p[i].second); 113 } 114 int main() 115 { 116 string op; 117 int cas,y,n; scanf("%d",&cas); 118 while(cas--) 119 { 120 now=0; 121 scanf("%d",&n); 122 p.clear(); 123 for(int k=1; k<=n; k++) 124 { 125 cin>>op; 126 printf("Operation #%d: ",k); 127 if(op=="Add") add(); 128 else if(op=="Close") close(); 129 else if(op=="Chat") chat(); 130 else if(op=="Rotate") {scanf("%d",&y);rot(y);} 131 else if(op=="Prior") prior(); 132 else if(op=="Choose") choose(); 133 else if(op=="Top") top(); 134 else if(op=="Untop") untop(); 135 } 136 bye(); 137 } 138 return 0; 139 }
hdu5073
方差贪心,最后答案一定是连续的n-k个组成的惯量,注意精度保护

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 int n,k,a[100010]; 6 int main() 7 { 8 int cas; 9 scanf("%d",&cas); 10 while (cas--) 11 { 12 scanf("%d%d",&n,&k); 13 for (int i=1; i<=n; i++) 14 scanf("%d",&a[i]); 15 sort(a+1,a+1+n); 16 if (k>=n-1) 17 { 18 puts("0"); 19 continue; 20 } 21 ll s1=0,s2=0; 22 for (int i=1; i<=n-k; i++) 23 { 24 s2+=1ll*a[i]*a[i]; 25 s1+=a[i]; 26 } 27 ll ans=1ll*(n-k)*s2-s1*s1; 28 for (int i=n-k+1; i<=n; i++) 29 { 30 s2+=1ll*a[i]*a[i]-1ll*a[i-n+k]*a[i-n+k]; 31 s1+=a[i]-a[i-n+k]; 32 ans=min(ans,1ll*(n-k)*s2-s1*s1); 33 } 34 printf("%.10lf ",1.0*ans/(n-k)); 35 } 36 }
hdu5074
简单dp

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int inf=-1000000007; 5 int f[2][60],a[60][60],n,m; 6 int main() 7 { 8 int cas; 9 scanf("%d",&cas); 10 while (cas--) 11 { 12 scanf("%d%d",&n,&m); 13 for (int i=1; i<=m; i++) 14 for (int j=1; j<=m; j++) 15 scanf("%d",&a[i][j]); 16 for (int i=1; i<=m; i++) f[0][i]=inf; 17 int x; 18 scanf("%d",&x); 19 if (x==-1) memset(f[0],0,sizeof(f[0])); else f[0][x]=0; 20 int p=0; 21 for (int i=2; i<=n; i++) 22 { 23 p^=1; 24 for (int j=1; j<=m; j++) f[p][j]=inf; 25 scanf("%d",&x); 26 if (x>-1) 27 { 28 for (int j=1; j<=m; j++) 29 f[p][x]=max(f[p][x],f[p^1][j]+a[j][x]); 30 } 31 else { 32 for (int j=1; j<=m; j++) 33 for (int k=1; k<=m; k++) 34 f[p][k]=max(f[p][k],f[p^1][j]+a[j][k]); 35 } 36 } 37 int ans=0; 38 for (int i=1; i<=m; i++) ans=max(ans,f[p][i]); 39 printf("%d ",ans); 40 } 41 }
hdu5078
水题简单模拟

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 double sqr(double x) 6 { 7 return x*x; 8 } 9 10 double dis(int x,int y,int x0,int y0) 11 { 12 return sqrt(sqr(x-x0)+sqr(y-y0)); 13 } 14 15 int main() 16 { 17 int cas,n; 18 scanf("%d",&cas); 19 while (cas--) 20 { 21 scanf("%d",&n); 22 double ans=0; 23 int x0,y0,x,y,t,t0; 24 scanf("%d%d%d",&t0,&x0,&y0); 25 for (int i=2; i<=n; i++) 26 { 27 scanf("%d%d%d",&t,&x,&y); 28 ans=max(ans,dis(x,y,x0,y0)/(t-t0)); 29 x0=x,y0=y,t0=t; 30 } 31 printf("%.10lf ",ans); 32 } 33 }
hdu5077
暴力dfs+剪枝,然后打表

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int ans[300]={1,5,6,3,6,3,7,4,7,8,4,5,4,5,4,1,6,3,7,4,7,4,9,7,8,8,7,5,7,5,7,4,7,8,4,5,8,8,7,5,8,9,5,6,8,8,5,5,4,5,4,1,7,5,7,4,8,8,5,5,5,7,6,4,7,8,8,8,4,5,7,5,8,9,8,8,5,6,5,5,4,5,7,5,4,1,7,4,8,8,5,7,5,5,6,4,8,9,8,8,8,8,5,7,11,9,8,9,8,9,8,8,5,6,5,5,5,5,6,4,8,9,8,8,8,8,8,7,8,9,9,9,9,9,10,9,5,7,6,6,6,6,7,6,9,9,10,9,10,9,10,10,7,6,7,7,7,7,9,7,5,7,6,6,7,6,7,7,5,6,2,3,6,6,4,3,6,6,7,6,7,7,9,7,6,6,4,3,7,7,7,6,5,7,7,6,6,6,7,7,5,6,6,6,2,3,4,3,6,6,7,7,7,6,9,7,6,6,7,7,4,3,7,6,5,6,6,6,6,6,7,7,8,9,5,6,5,6,2,5,2,3,4,3,4,3,7,6,5,6,2,5,2,5,4,1}; 6 7 int main() 8 { 9 int cas; 10 char s[10]; 11 scanf("%d",&cas); 12 while (cas--) 13 { 14 scanf("%s",s); 15 int n=0; 16 for (int i=0; i<8; i++) 17 { 18 n<<=1; 19 n|=s[i]-'0'; 20 } 21 printf("%d ",ans[n]); 22 } 23 }
hdu5860
设编号0~n-1,a[i]为第i轮死,则a[i]=(i%k)?a[i-i/k-1]+1:1,然后整理一下就好

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int a[3000010],ans[3000010],g[3000010],nex[3000010],p[3000010],len,n,m,q; 6 void add(int x,int y) 7 { 8 g[++len]=y; 9 nex[len]=p[x]; 10 p[x]=len; 11 } 12 13 int main() 14 { 15 int cas; 16 scanf("%d",&cas); 17 while (cas--) 18 { 19 scanf("%d%d%d",&n,&m,&q); 20 len=0; int mx=1; 21 for (int i=0; i<n; i++) 22 { 23 if (i%m) a[i]=a[i-i/m-1]+1; 24 else a[i]=1; 25 mx=max(a[i],mx); 26 } 27 for (int i=n-1; i>=0; i--) add(a[i],i+1); 28 int t=0; 29 for (int i=1; i<=mx; i++) 30 for (int j=p[i]; j; j=nex[j]) ans[++t]=g[j]; 31 while (q--) 32 { 33 int x; scanf("%d",&x); 34 printf("%d ",ans[x]); 35 } 36 for (int i=1; i<=mx; i++) p[i]=0; 37 } 38 }
hdu5861
维护每条线段最早和最迟用到为第几天,然后差分计算答案

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int ans[200010],mx[800010],mi[800010],w[200010],n,m; 5 void push(int i) 6 { 7 if (mi[i]<=m) 8 { 9 mi[i*2]=min(mi[i*2],mi[i]); 10 mi[i*2+1]=min(mi[i*2+1],mi[i]); 11 mi[i]=m+1; 12 } 13 if (mx[i]) 14 { 15 mx[i*2]=max(mx[i*2],mx[i]); 16 mx[i*2+1]=max(mx[i*2+1],mx[i]); 17 mx[i]=0; 18 } 19 } 20 21 void build(int i,int l,int r) 22 { 23 mx[i]=0; mi[i]=m+1; 24 if (l!=r) 25 { 26 int m=(l+r)>>1; 27 build(i*2,l,m); 28 build(i*2+1,m+1,r); 29 } 30 } 31 32 void add(int i,int l,int r,int x,int y,int z) 33 { 34 if (x<=l&&y>=r) 35 { 36 mi[i]=min(mi[i],z); 37 mx[i]=max(mx[i],z); 38 } 39 else { 40 int m=(l+r)>>1; 41 push(i); 42 if (x<=m) add(i*2,l,m,x,y,z); 43 if (y>m) add(i*2+1,m+1,r,x,y,z); 44 } 45 } 46 47 void ask(int i,int l,int r) 48 { 49 if (l==r) 50 { 51 if (mx[i]>=mi[i]) 52 { 53 ans[mi[i]]+=w[l]; 54 ans[mx[i]+1]-=w[l]; 55 } 56 } 57 else { 58 int m=(l+r)>>1; 59 push(i); 60 ask(i*2,l,m); 61 ask(i*2+1,m+1,r); 62 } 63 } 64 65 int main() 66 { 67 while (scanf("%d%d",&n,&m)!=EOF) 68 { 69 for (int i=1; i<n; i++) scanf("%d",&w[i]); 70 memset(ans,0,sizeof(ans)); 71 if (n-1) build(1,1,n-1); 72 for (int i=1; i<=m; i++) 73 { 74 int x,y; 75 scanf("%d%d",&x,&y); 76 if (x>y) swap(x,y); 77 if (n-1) add(1,1,n-1,x,y-1,i); 78 } 79 if (n-1) ask(1,1,n-1); 80 for (int i=1; i<=m; i++) ans[i]+=ans[i-1]; 81 for (int i=1; i<=m; i++) printf("%d ",ans[i]); 82 } 83 }
hdu5862
只有可能竖直线段和横向线段有交点,那么就是经典的扫描线了:x排序,维护y,竖直线段查询,横向线段“头进尾出”

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 struct node{int x,l,r,id;} a[200010]; 6 int tr[200010*4],b[200010],n; 7 8 bool cmp(node a,node b) 9 { 10 if (a.x==b.x) return a.id<b.id; 11 return a.x<b.x; 12 } 13 14 void build(int i,int l,int r) 15 { 16 tr[i]=0; 17 if (l!=r) 18 { 19 int m=(l+r)>>1; 20 build(i*2,l,m); 21 build(i*2+1,m+1,r); 22 } 23 } 24 25 void add(int i,int l,int r,int x,int y) 26 { 27 if (l==r) tr[i]+=y; 28 else { 29 int m=(l+r)>>1; 30 if (x<=m) add(i*2,l,m,x,y); 31 else add(i*2+1,m+1,r,x,y); 32 tr[i]=tr[i*2]+tr[i*2+1]; 33 } 34 } 35 36 int ask(int i,int l,int r,int x,int y) 37 { 38 if (x<=l&&y>=r) return tr[i]; 39 else { 40 int m=(l+r)>>1,s=0; 41 if (x<=m) s+=ask(i*2,l,m,x,y); 42 if (y>m) s+=ask(i*2+1,m+1,r,x,y); 43 return s; 44 } 45 } 46 47 int main() 48 { 49 int cas; 50 scanf("%d",&cas); 51 while (cas--) 52 { 53 scanf("%d",&n); 54 int t=0,m=0; 55 for (int i=1; i<=n; i++) 56 { 57 int x1,y1,x2,y2; 58 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 59 b[++m]=y1; b[++m]=y2; 60 if (x1==x2) 61 { 62 a[++t].x=x1; 63 if (y1>y2) swap(y1,y2); 64 a[t].l=y1; a[t].r=y2; 65 a[t].id=2; 66 } 67 else { 68 if (x1>x2) swap(x1,x2); 69 a[++t].x=x1; 70 a[t].l=a[t].r=y1; a[t].id=1; 71 a[++t].x=x2+1; 72 a[t].l=a[t].r=y1; a[t].id=-1; 73 } 74 } 75 sort(a+1,a+1+t,cmp); 76 sort(b+1,b+1+m); 77 m=unique(b+1,b+m+1)-b-1; 78 for (int i=1; i<=t; i++) 79 { 80 a[i].l=lower_bound(b+1,b+1+m,a[i].l)-b; 81 if (a[i].id==2) a[i].r=lower_bound(b+1,b+1+m,a[i].r)-b; 82 } 83 build(1,1,m); 84 ll ans=0; 85 for (int i=1; i<=t; i++) 86 if (a[i].id==2) ans+=ask(1,1,m,a[i].l,a[i].r); 87 else add(1,1,m,a[i].l,a[i].id); 88 89 printf("%lld ",ans); 90 } 91 }
hdu5961
把P图建出来找出环则为N,再把Q图反向找出环也为N

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int d[2050],q[2050],n; 5 vector<int> g[2050]; 6 pair<int,int> w[2200000]; 7 char s[2050]; 8 9 bool cycle() 10 { 11 int f=1,r=0; 12 memset(d,0,sizeof(d)); 13 for (int i=1; i<=n; i++) 14 for (int j=0; j<g[i].size(); j++) d[g[i][j]]++; 15 for (int i=1; i<=n; i++) 16 if (!d[i]) q[++r]=i; 17 while (f<=r) 18 { 19 int x=q[f++]; 20 for (int i=0; i<g[x].size(); i++) 21 { 22 int y=g[x][i]; 23 if (--d[y]==0) q[++r]=y; 24 } 25 } 26 return r<n; 27 } 28 29 int main() 30 { 31 int cas; 32 scanf("%d",&cas); 33 while (cas--) 34 { 35 scanf("%d",&n); 36 for (int i=1; i<=n; i++) g[i].clear(); 37 int t=0; 38 for (int i=1; i<=n; i++) 39 { 40 scanf("%s",s+1); 41 for (int j=1; j<=n; j++) 42 if (s[j]=='P') g[i].push_back(j); 43 else if (s[j]=='Q') w[++t]=make_pair(i,j); 44 } 45 if (cycle()) {puts("N"); continue;} 46 else { 47 for (int i=1; i<=t; i++) 48 g[w[i].second].push_back(w[i].first); 49 if (cycle()) puts("N"); 50 else puts("T"); 51 } 52 } 53 }
hdu5802
尽可能的往下,处理一下停顿就好

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int p,q; 5 6 int dfs(int p,int ans,int s) 7 { 8 if (p==q) return ans; 9 int x=0; 10 while (p-(1<<x)+1>q) x++; 11 if (p-(1<<x)+1==q) return ans+x; 12 int ans0=ans+x+max(0,q-max(0,p+1-(1<<x))-s); 13 return min(ans0,dfs(p-(1<<(x-1))+1,ans+x,s+1)); 14 } 15 16 int main() 17 { 18 int cas; 19 scanf("%d",&cas); 20 while (cas--) 21 { 22 scanf("%d%d",&p,&q); 23 if (q>=p) printf("%d ",q-p); 24 else printf("%d ",dfs(p,0,0)); 25 } 26 }