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 }
