A
#include <iostream> #include<algorithm> #include <string.h> #include <cstdio> #include <vector> using namespace std; struct point { int x,p; bool operator < (const point &rhs)const { return x<rhs.x; } }P[105]; int main() { int n; while(scanf("%d",&n)==1) { for(int i=0; i<n;i++) { scanf("%d%d",&P[i].x,&P[i].p); } sort(P,P+n); int loc=-1; for(int i=0; i<n; i++) if(P[i].x>0){ loc=i;break; } if(loc==-1){ printf("%d ",P[n-1].p);continue; } if(loc==0){ printf("%d ",P[0].p);continue; } long long ans=0; int L=0; while(true) { if(loc+L>=n||loc-L-1<0){ if(loc+L>=n){ ans+=P[loc-L-1].p; }else ans+=P[loc+L].p; break; } ans+=P[loc+L].p+P[loc-L-1].p; L++; } printf("%I64d ",ans); } return 0; }
B
#include <iostream> #include<algorithm> #include <string.h> #include <cstdio> #include <vector> using namespace std; const int maxn=1000006; int num[maxn]; int L[maxn],R[maxn]; int main() { int n; while(scanf("%d",&n)==1) { memset(num,0,sizeof(num)); for(int i=1; i<=n;i++){ int a; scanf("%d",&a); if(num[a]==0){ L[a]=i;R[a]=i; }else { R[a]=i; } num[a]++; } int id=0; for(int i=0; i<=1000000; i++) if(num[i]>num[id])id=i; int cL=L[id],cR=R[id]; for(int i=0; i<=1000000; i++) if(num[i]==num[id]&&R[i]-L[i]<R[id]-L[id]) id=i; printf("%d %d ",L[id],R[id]); } return 0; }
C
首先将第一个点能到的数值计算出来 我们要知道 最后相等的时候肯定是第一个点他要能够达到,那么最多就10多种可能,然后接着除了下降的值外,要翻倍的值就如果在1中没有出现那么就不要他了因为那个值 第一个试管的体积到不到,然后bfs 找状态就好了
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> #include <set> #include <queue> using namespace std; const int maxn=100005; int a[maxn+10],num[maxn+10]; struct point{ int x,stp; point(int a=0,int b=0){ x=a; stp=b; } }; bool use[maxn*2]; int mark[maxn*2]; void solve(int d,int id) { queue<point>Q; mark[d]=id; num[d]++; Q.push(point(d,0)); while(!Q.empty()) { point t=Q.front();Q.pop(); if(t.x*2<=maxn&&use[t.x*2]) { if(mark[t.x*2]!=id){ mark[t.x*2]=id; num[t.x*2]++; a[t.x*2]+=t.stp+1; Q.push(point(t.x*2,t.stp+1)); } } if(t.x/2>0) { if(mark[t.x/2]!=id){ mark[t.x/2]=id; num[t.x/2]++; a[t.x/2]+=t.stp+1; Q.push(point(t.x/2,t.stp+1)); } } } } void init(int d) { queue<int>Q; Q.push(d); use[d]=true; while(!Q.empty()) { int t=Q.front();Q.pop(); if(t*2<maxn) { if(use[t*2]==false){ use[t*2]=true; Q.push(t*2); } } if(t/2>0) { if(use[t/2]==false){ use[t/2]=true; Q.push(t/2); } } } } int C[maxn]; int main() { int n; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&C[i]); } if(n==1){ printf("0 ");return 0; } init(C[0]); for(int i=0; i<n; i++) { solve(C[i],i+1); } int ans=2147483647; for(int i=1; i<maxn;i++) if(num[i]==n) { ans=min(ans,a[i]); } printf("%d ",ans); return 0; }
D
我们将每个影响都不断地扩大知道最后一层,然后采用
线段树 先把赋值为0的操作全做了,然后在做存在操作,如果值为0那么就不要操作了,这样判断是否成功
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <vector> using namespace std; const int maxn=100005*6; typedef long long LL; struct elem { LL I,L,R; elem(LL cI=0,LL cL=0,LL cR=0) { I=cI; L=cL; R=cR; } }A[100005],B[100005]; LL C[maxn],ge; struct Itree { LL val[100000*30]; LL cL,cR,ans,loc; void build(int L, int R, int o) { if(L==R) { val[o]=1;return ; } int mid=(L+R)>>1; build(L,mid,o*2); build(mid+1,R,o*2+1); val[o]=val[o*2]+val[o*2+1]; } void update(int L, int R, int o){ if(cL<=L && R<=cR) { val[o]=0; return ; } if(val[o]==0)return ; int mid=(L+R)>>1; if(cL<=mid) update(L,mid, o*2); if(cR>mid) update(mid+1,R,o*2+1); val[o]=val[o*2]+val[o*2+1]; } void query(int L,int R, int o) { if(L==R){ if(val[o]!=0){ loc=L; ans+=val[o]; } return ; } int mid=(L+R)>>1; if(val[o]==0){ val[o*2]=val[o*2+1]=0; } if(cL<=mid) query(L,mid,o*2); if(cR>mid) query(mid+1,R,o*2+1); } }T; int h,q; void add(LL d) { C[ge++]=d; if( ( d + 1 ) <= ( (1LL<<h) - 1) ){ C[ge++]=d+1; } if(d-1>=( 1LL<<(h-1) ) ){ C[ge++]=d-1; } } int main() { int c0=0,c1=0; scanf("%d%d",&h,&q); for(int i=0; i<q; i++) { LL I,L,R,ans; scanf("%I64d%I64d%I64d%I64d",&I,&L,&R,&ans); while( (L*2LL) < (1LL<<h) ){ L=(L*2); } while( (R*2LL+1) < (1LL<<h) ){ R=(R*2)+1; } if(L>R)swap(L,R); if(ans==0){ A[c0++]=elem(I,L,R); }else{ B[c1++]=elem(I,L,R); } } LL L=1LL<<(h-1),R=(1LL<<h)-1; int cor=0; for(int i=0; i<c1; i++) { L=max(B[i].L,L); R=min(B[i].R,R);if(L>R){cor=1;break;} } for(int i=0; i<c1; i++) { if( (B[i].L<=L&&B[i].R>=R) ==false ){ cor=1; break; } } if(cor==1){ puts("Game cheated!"); return 0;} ge=0; C[ge++]=1LL<<(h-1); C[ge++]=(1LL<<h)-1; add(L); add(R); for(int i=0; i<c0; i++) { add(A[i].L); add(A[i].R); } sort(C,C+ge); ge=unique(C,C+ge)-C; T.build(1,ge,1); for(int i=0; i<c0; i++) { T.cL=lower_bound(C,C+ge,A[i].L)-C+1; T.cR=lower_bound(C,C+ge,A[i].R)-C+1; T.update(1,ge,1); } T.ans=0; T.cL=lower_bound(C,C+ge,L)-C+1; T.cR=lower_bound(C,C+ge,R)-C+1; T.query(1,ge,1); if(T.ans==0) { puts("Game cheated!"); }else if(T.ans>1){ puts("Data not sufficient!"); }else { printf("%I64d ",C[T.loc-1]); } return 0; }
E
线段树存的是 字母个数,然后我们就直接用字母个数进行类似 基数排序得到答案
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> using namespace std; const int maxn=100005; char str[maxn+10]; struct Itree { int s[maxn*4]; int val[maxn*4][26],cL,cR,cK; int ch[26]; void maintain(int o) { for(int i=0; i<26; i++) val[o][i]=val[ o * 2 ][ i ]+val[ o*2 + 1 ][ i ]; } void build(int L, int R, int o) { memset(val[o],0,sizeof(val[o])); s[o]=0; if(L==R){ val[o][str[L-1]-'a' ]++; return ; } int mid=(L+R)>>1; build(L,mid,o*2); build(mid+1,R,o*2+1); maintain(o); } void nondecreasing(int L,int R, int o) { int mid=(R+L)>>1; int cur=mid-L+1,nu=0; for(int i=0; i<26; i++) { if( val[ o ][ i ] + nu <= cur ){ val[ o*2 ][ i ] = val[ o ][ i ]; nu += val[ o ][ i ]; val[ o ][ i ] = 0; }else{ val[ o * 2 ][ i ]=cur-nu; val[o][i]-=(cur-nu); nu=cur; } if(nu==cur)break; } for(int i=0; i<26; i++) { val[o*2+1][i]=val[o][i]; val[o][i]=0; } } void nonincreasing(int L, int R, int o) { int mid=(R+L)>>1; int cur=mid-L+1,nu=0; for(int i=25; i>=0; i--) { if( val[ o ][ i ] + nu <= cur ){ val[ o*2 ][ i ] = val[ o ][ i ]; nu += val[ o ][ i ]; val[ o ][ i ] = 0; }else { val[ o * 2 ][ i ]=cur-nu; val[o][i]-=(cur-nu); nu=cur; } if(nu==cur)break; } for(int i=25; i>=0; i--) { val[o*2+1][i]=val[o][i]; val[o][i]=0; } } void downmatain(int L, int R,int o) { memset(val[o*2],0,sizeof(val[o*2])); memset(val[o*2+1],0,sizeof(val[o*2+1])); s[o*2+1]=s[o*2]=s[o]; if(s[o]==1){ nonincreasing(L,R,o); }else if(s[o]==2){ nondecreasing(L,R,o); } s[o]=0; } void query(int L, int R, int o) { if(cL<=L&&R<=cR) { for(int i=0; i<26; i++) ch[i]+=val[o][i]; return ; } if(s[o]!=0) downmatain(L,R,o); int mid=(L+R)>>1; if(cL<=mid) query(L,mid,o*2); if(cR>mid) query(mid+1,R,o*2+1); maintain(o); } void Knondecreasing(int L,int R, int o)//递增 { int cur=R-L+1,nu=0; for(int i=0; i<26; i++) { if(ch[i]+nu<=cur) { val[o][i]=ch[i]; nu+=ch[i]; ch[i]=0; }else{ val[o][i]=cur-nu; ch[i]-=(cur-nu); nu=cur; } if(nu==cur)break; } } void Knonincreasing(int L, int R, int o)//递减 { int cur=R-L+1,nu=0; for(int i=25; i>=0; i--) { if(ch[i]+nu<=cur){ val[o][i]=ch[i]; nu+=ch[i]; ch[i]=0; }else{ val[o][i]=cur-nu; ch[i]-=(cur-nu); nu=cur; } } } void update(int L, int R, int o) { if(cL<=L && R<=cR) { s[o]=cK; memset(val[o],0,sizeof(val[o])); if(cK==1) Knonincreasing(L,R,o); else Knondecreasing(L,R,o); return ; } int mid=(L+R)>>1; if(s[o]!=0) { downmatain(L,R,o); } if(cL<=mid)update(L,mid,o*2); if(cR>mid) update(mid+1,R,o*2+1); maintain(o); } void print(int L, int R, int o) { if(L==R){ for(int i=0; i<26; i++) if(val[o][i]!=0){ printf("%c",'a'+i); return ; } } if(s[o]!=0) downmatain(L,R,o); int mid=(L+R)>>1; print(L,mid,o*2); print(mid+1,R,o*2+1); // maintain(o); } }T; int main() { int n,q; scanf("%d%d",&n,&q); scanf("%s",str); T.build(1,n,1); memset(T.ch,0,sizeof(T.ch)); for(int i=1; i<=q; i++) { int L,R,k; scanf("%d%d%d",&L,&R,&k); T.cL=L;T.cR=R; T.cK=k+1; T.query(1,n,1); T.update(1,n,1); // T.print(1,n,1); } T.print(1,n,1);puts(""); return 0; }