思路:贪心。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100010 using namespace std; int n,tim; struct nond{ int end,t,be; }v[MAXN]; int cmp(nond a,nond b){ return a.end>b.end; } int main(){ freopen("manage.in","r",stdin); freopen("manage.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&v[i].t,&v[i].end); v[i].be=v[i].end-v[i].t; } sort(v+1,v+1+n,cmp); tim=v[1].end; for(int i=1;i<=n;i++) tim=min(tim-v[i].t,v[i].be); if(tim<0) cout<<"-1"<<endl; else cout<<tim<<endl; } /* 4 3 5 10 14 5 20 1 16 */
思路:组合数学。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100100 #define MAXM 501000 #define mod 998244353 using namespace std; int n,col[MAXN]; long long ans,sum,tot; long long C[5010][5010]; int main(){ freopen("qiang.in","r",stdin); freopen("qiang.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&col[i]); tot+=col[i]; } C[0][0]=1; for(int i=1;i<=tot;i++) for(int j=0;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; ans=1;sum=0; for(int i=1;i<=n;i++){ ans=ans*C[sum+col[i]-1][col[i]-1]%mod; sum+=col[i]; } cout<<ans<<endl; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mod=998244353; int f[500005]; int num[100005]; int sum; int pow(int a,int b,int p){ int ret=1%p; while(b){ if(b&1) ret=ret*1LL*a%p; b>>=1; a=a*1LL*a%p; } return ret; } int c(int n,int m){ if(m>n) return 0; return f[n]*1LL*pow(f[m],mod-2,mod)%mod*pow(f[n-m],mod-2,mod)%mod; } int main(){ freopen("qiang.in","r",stdin); freopen("qiang.out","w",stdout); f[0]=1; for(int i=1;i<=500000;i++) f[i]=f[i-1]*1LL*i%mod; int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=1;i<=n;i++) sum+=num[i]; int ans=1; for(int i=n;i>=1;i--){ ans=ans*1LL*c(sum-1,num[i]-1)%mod; sum-=num[i]; } printf("%d\n",ans); return 0; }
思路:
用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所有数的和。
用树状数组维护数组的话可以很方便的计算出某个区间内所有数的和以及修改某个数。
每次查询时,如果在中间块的函数,我们直接加上sum[i](sum[i]为预处理的每一块的和),对于两边的函数,就用树状数组快速求一下和即可。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef unsigned long long LL; #define lowbit(x) ((x)&-(x)) int n; int a[100005]; LL c[100005]; int L[100005],R[100005]; int Q; int t[405][100005]; int belong[100005];// (i-1)/B+1 LL sum[405]; int B,NUM; void add(int x,LL d){ while(x<=n){ c[x]+=d; x+=lowbit(x); } } LL ask(int x){ LL ret=0; while(x){ ret+=c[x]; x-=lowbit(x); } return ret; } int main(){ freopen("sum.in","r",stdin); freopen("sum.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=n;i++){ scanf("%d%d",&L[i],&R[i]); } B=sqrt(n)+1; NUM=(n-1)/B+1; for(int i=1;i<=n;i++) belong[i]=(i-1)/B+1; for(int i=1;i<=n;i++) c[i]=a[i]; for(int i=1;i<=n;i++){ if(i+lowbit(i)<=n){ c[i+lowbit(i)]+=c[i]; } } for(int i=1;i<=n;i++){ t[belong[i]][L[i]]++; t[belong[i]][R[i]+1]--; } for(int i=1;i<=NUM;i++){ for(int j=1;j<=n;j++){ t[i][j]+=t[i][j-1]; sum[i]+=t[i][j]*1ULL*a[j]; } } scanf("%d",&Q); while(Q--){ int type,x,y; scanf("%d%d%d",&type,&x,&y); if(type==1){ for(int i=1;i<=NUM;i++){ sum[i]-=t[i][x]*1ULL*a[x]; sum[i]+=t[i][x]*1ULL*y; } add(x,-a[x]); a[x]=y; add(x,a[x]); }else{ int Ln,Rn; Ln=belong[x],Rn=belong[y]; LL ans=0; if(Ln==Rn){ for(int i=x;i<=y;i++){ ans+=ask(R[i])-ask(L[i]-1); } }else{ for(int i=Ln+1;i<Rn;i++) ans+=sum[i]; int lim; lim=Ln*B; lim=min(lim,y); for(int i=x;i<=lim;i++){ ans+=ask(R[i])-ask(L[i]-1); } lim=(Rn-1)*B+1; lim=max(lim,x); for(int i=lim;i<=y;i++){ ans+=ask(R[i])-ask(L[i]-1); } } printf("%I64d\n",ans); } } fclose(stdout); return 0; }