http://oj.jxust.edu.cn/contest?id=1702
A :::
思路::开一个数组暂时记录一下每个杯子加的水量(假设无穷大);再遍历一便数组如果大于当前杯子的容量,则将多余的水量移至下一水杯
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn=1e5+5; 5 6 ll a[maxn],b[maxn]; 7 int n,m; 8 int main() 9 { 10 int t; 11 scanf("%d",&t); 12 while(t--){ 13 //memset(b,0,sizeof(b)); 14 scanf("%d%d",&n,&m); 15 for(int i=1;i<=n;i++){ 16 scanf("%lld",&a[i]); 17 b[i]=0; 18 } 19 while(m--){ 20 int x; 21 ll y; 22 scanf("%d%lld",&x,&y); 23 b[x]+=y; 24 } 25 ll jw=0; 26 for(int i=1;i<=n;i++){ 27 if(b[i]+jw>a[i]){ 28 jw=b[i]+jw-a[i]; 29 b[i]=a[i]; 30 } 31 else if(b[i]+jw<a[i]){ 32 b[i]=b[i]+jw;jw=0; 33 } 34 else if(b[i]+jw==a[i]){ 35 b[i]=a[i];jw=0; 36 } 37 } 38 for(int i=1;i<=n;i++){ 39 if(i==1){printf("%lld",b[i]);} 40 else{printf(" %lld",b[i]); 41 } 42 } 43 printf("\n"); 44 } 45 return 0; 46 }
B :::
思路:: 预处理:线性筛素数 枚举两个素数,再判断第三个数是否为素数(三个素数的关系 第一个素数 <= 第二个素数 <= 第三个素数 )避免重复计数
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn=4e4+5; 5 const int Maxn=1e8; 6 7 bool isprime[maxn]; 8 int prime[maxn]; 9 int num_prime=0; 10 void get_prime() 11 { 12 isprime[0]=1; 13 isprime[1]=1; 14 for(int i=2;i<=maxn;i++){ 15 if(!isprime[i]){ 16 prime[num_prime++]=i; 17 } 18 for(int j=0;j<num_prime&&i*prime[j]<=maxn;j++){ 19 isprime[i*prime[j]]=1; 20 if(i%prime[j]==0){break;} 21 } 22 } 23 } 24 int main() 25 { 26 get_prime(); 27 int t; 28 scanf("%d",&t); 29 while(t--){ 30 int n; 31 scanf("%d",&n); 32 if(n<=5){ 33 printf("0\n");continue; 34 } 35 int sum=0; 36 for(int i=0;prime[i]<=n;i++){ 37 for(int j=i;prime[j]+prime[i]<=n;j++){ 38 if(isprime[n-prime[i]-prime[j]]==0&&(n-prime[i]-prime[j])>=prime[j]){sum++;} 39 } 40 } 41 cout<<sum<<endl; 42 } 43 return 0; 44 }
C :::
思路::分别对 x y z 排序,再对全部建立的边排序,再跑一下克鲁斯卡尔即可;
由题意可以知当你在某两点之间建立边时,你只会用 X,Y,Z 中的一种建立,而对X排序的话保证了相邻的两点建边花费最小(必然不会选择与其他点建立),对Y,Z同样的道理,跑克鲁斯卡尔
1 //#include<bits/stdc++.h> 2 #include<iostream> 3 #include<stdio.h> 4 #include<string> 5 #include<string.h> 6 #include<algorithm> 7 #include<stack> 8 #include<set> 9 #include<map> 10 #define ll long long 11 using namespace std; 12 const int maxn=2e5+5; 13 const int inf=1e9+7; 14 15 struct node 16 { 17 int x,y,z,pos,val; 18 }a[maxn],b[maxn*3]; 19 int f[maxn]; 20 bool cmp1(node A,node B) 21 { 22 return A.x<B.x; 23 } 24 bool cmp2(node A,node B) 25 { 26 return A.y<B.y; 27 } 28 bool cmp3(node A,node B) 29 { 30 return A.z<B.z; 31 } 32 bool cmp4(node A,node B) 33 { 34 return A.val<B.val; 35 } 36 int getfind(int x) 37 { 38 return f[x]==x?x:f[x]=getfind(f[x]); 39 } 40 int main() 41 { 42 int n; 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++){ 45 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); 46 a[i].pos=i; 47 f[i]=i; 48 } 49 int ant=0; 50 sort(a+1,a+n+1,cmp1); 51 for(int i=1;i<n;i++){ 52 b[++ant].x=a[i].pos; 53 b[ant].y=a[i+1].pos; 54 b[ant].val=abs(a[i].x-a[i+1].x); 55 } 56 sort(a+1,a+n+1,cmp2); 57 for(int i=1;i<n;i++){ 58 b[++ant].x=a[i].pos; 59 b[ant].y=a[i+1].pos; 60 b[ant].val=abs(a[i].y-a[i+1].y); 61 } 62 sort(a+1,a+n+1,cmp3); 63 for(int i=1;i<n;i++){ 64 b[++ant].x=a[i].pos; 65 b[ant].y=a[i+1].pos; 66 b[ant].val=abs(a[i].z-a[i+1].z); 67 } 68 sort(b+1,b+ant+1,cmp4); 69 int cnt=1,sum=0; 70 for(int i=1;i<=ant;i++){ 71 int t1=getfind(b[i].x); 72 int t2=getfind(b[i].y); 73 if(t1!=t2){ 74 f[t2]=t1; 75 cnt++; 76 sum+=b[i].val; 77 } 78 if(cnt>=n){break;} 79 } 80 cout<<sum<<endl; 81 return 0; 82 }
D :::
思路::
E :::
思路::
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn=4e4+5; 5 const int Maxn=1e8; 6 7 ll a[105]; 8 ll exgcd(ll a,ll b,ll &x,ll &y) 9 { 10 if(b==0){ 11 x=1; 12 y=0; 13 return a; 14 } 15 int r=exgcd(b,a%b,x,y); 16 int t=x; 17 x=y; 18 y=t-a/b*y; 19 return t; 20 } 21 int main() 22 { 23 ll n; 24 scanf("%lld",&n); 25 a[1]=1,a[2]=2,a[3]=3,a[4]=4; 26 for(ll i=5;i<=n;i++){ 27 ll ans=0; 28 for(ll j=1;j<=i/2;j++){ 29 ans=max(ans,a[j]*a[i-j]); 30 } 31 a[i]=ans; 32 } 33 ll x,y; 34 exgcd(n,a[n],x,y); 35 printf("%lld\n",(x+a[n])%a[n]); 36 return 0; 37 }
F :::
思路::线段树区间更新,只需对lazy标记处理,只有 lazy值为奇数时反转,
1 //#include <bits/stdc++.h> 2 #include<string.h> 3 #include<stdio.h> 4 #include<iostream> 5 #include<string> 6 #include<algorithm> 7 #define ll long long 8 using namespace std; 9 10 const int maxn=1e5+5; 11 int lazy[maxn<<2]; 12 13 void build(int l,int r,int rt) 14 { 15 lazy[rt]=0; 16 if(l==r){ 17 return ; 18 } 19 int mid=(l+r)>>1; 20 build(l,mid,2*rt); 21 build(mid+1,r,2*rt+1); 22 } 23 void pushup(int rt) 24 { 25 if(lazy[rt]!=0){ 26 if(lazy[rt]%2==0){lazy[rt]=0;return ;} 27 lazy[2*rt]+=lazy[rt]; 28 lazy[2*rt+1]+=lazy[rt]; 29 lazy[rt]=0; 30 } 31 } 32 void update(int L,int R,int l,int r,int rt) 33 { 34 if(L<=l&&R>=r){ 35 lazy[rt]++; 36 return ; 37 } 38 pushup(rt); 39 int mid=(l+r)>>1; 40 if(L<=mid){ 41 update(L,R,l,mid,2*rt); 42 } 43 if(mid<R){ 44 update(L,R,mid+1,r,2*rt+1); 45 } 46 } 47 int query(int tr,int l,int r,int rt) 48 { 49 if(l==r){ 50 if(lazy[rt]&1){ 51 return 1; 52 } 53 else{ 54 return 0; 55 } 56 } 57 pushup(rt); 58 int mid=(l+r)>>1; 59 if(tr<=mid){ 60 query(tr,l,mid,2*rt); 61 } 62 else{ 63 query(tr,mid+1,r,2*rt+1); 64 } 65 } 66 int main() 67 { 68 int n,m; 69 scanf("%d%d",&n,&m); 70 build(1,n,1); 71 while(m--) 72 { 73 int op,a,b; 74 scanf("%d",&op); 75 if(op==1){ 76 scanf("%d%d",&a,&b); 77 update(a,b,1,n,1); 78 } 79 else{ 80 scanf("%d",&a); 81 printf("%d\n",query(a,1,n,1)); 82 } 83 } 84 return 0; 85 }
G :::
思路::
阶乘逆元模板
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn=1e5+5; 5 const ll MOD=1e9+7; 6 7 ll fa[maxn],inv[maxn]; 8 ll qpow(ll x,ll p) 9 { 10 ll ans=1; 11 while(p){ 12 if(p&1){ 13 ans=(ans*x)%MOD; 14 } 15 x=(x*x)%MOD; 16 p>>=1; 17 } 18 return ans; 19 } 20 void pre() 21 { 22 fa[0]=1; 23 for(int i=1;i<=maxn;i++){ 24 fa[i]=(fa[i-1]*i)%MOD; 25 } 26 inv[maxn]=qpow(fa[maxn],MOD-2); 27 for(int i=maxn-1;i>=0;i--){ 28 inv[i]=inv[i+1]*(i+1)%MOD; 29 } 30 } 31 int main() 32 { 33 pre(); 34 int n; 35 scanf("%d",&n); 36 if(n==1){ 37 printf("0\n");return 0; 38 } 39 ll sum=0; 40 for(int i=2;i<=n;i++){ 41 sum=(sum+fa[n]*inv[i]%MOD*inv[n-i]%MOD*(qpow(2,i)-2)%MOD)%MOD; 42 } 43 printf("%lld\n",sum); 44 return 0; 45 }