A.
显然构造一个蛇形就行了
复杂度(O(r*c))
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 #define maxn 105 8 using namespace std; 9 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 10 ll fastpow(ll a,ll p,ll mod) 11 { 12 ll ans=1; 13 while(p) 14 { 15 if(p&1)ans=ans*a%mod; 16 a=a*a%mod;p>>=1; 17 } 18 return ans; 19 } 20 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 21 int T,n,m,k; 22 char a[maxn][maxn]; 23 int Ans[maxn][maxn]; 24 int nx[maxn][maxn],ny[maxn][maxn]; 25 char ID(int x) 26 { 27 if(1<=x&&x<=26)return x-1+'a'; 28 if(27<=x&&x<=52)return x-27+'A'; 29 if(53<=x&&x<=62)return x-53+'0'; 30 } 31 int main() 32 { 33 scanf("%d",&T); 34 while(T--) 35 { 36 scanf("%d%d%d",&n,&m,&k); 37 for(int i=0;i<=n+1;++i) 38 for(int j=0;j<=m+1;++j)nx[i][j]=ny[i][j]=Ans[i][j]=0; 39 for(int i=1;i<=n;++i) 40 { 41 for(int j=1;j<=m;++j)nx[i][j]=i,ny[i][j]=(i&1)?j+1:j-1; 42 if(i&1)nx[i][m]=i+1,ny[i][m]=m; 43 else nx[i][1]=i+1,ny[i][1]=1; 44 } 45 for(int i=1;i<=n;++i)scanf("%s",a[i]+1); 46 int num=0; 47 for(int i=1;i<=n;++i) 48 for(int j=1;j<=m;++j)if(a[i][j]=='R')num++; 49 int t=num/k; 50 int k1=num-t*k; 51 int k2=k-k1; 52 int nowx=1,nowy=1; 53 for(int p=1;p<=k1;++p) 54 { 55 int cnt=0; 56 while(cnt<t+1) 57 { 58 Ans[nowx][nowy]=p; 59 if(a[nowx][nowy]=='R')cnt++; 60 int xx=nx[nowx][nowy],yy=ny[nowx][nowy]; 61 nowx=xx,nowy=yy; 62 } 63 } 64 for(int p=k1+1;p<=k1+k2;++p) 65 { 66 int cnt=0; 67 while(cnt<t) 68 { 69 Ans[nowx][nowy]=p; 70 if(a[nowx][nowy]=='R')cnt++; 71 int xx=nx[nowx][nowy],yy=ny[nowx][nowy]; 72 nowx=xx,nowy=yy; 73 } 74 } 75 while(nowx&&nowy) 76 { 77 Ans[nowx][nowy]=k1+k2; 78 int xx=nx[nowx][nowy],yy=ny[nowx][nowy]; 79 nowx=xx,nowy=yy; 80 } 81 for(int i=1;i<=n;++i) 82 { 83 for(int j=1;j<=m;++j)printf("%c",ID(Ans[i][j])); 84 puts(""); 85 } 86 } 87 }
B.
设总和为(tot),则我们考虑枚举(tot)的约数,然后check
假设这个约数是(k)
check做法:先把每个数 ( mod k),然后把一段一段和为(k)的段抠出来
然后枚举移动到的位置,取最优
这样B1就做完了,复杂度(O(n*d(w)))
然后发现B2的(tot)太大,约数太多,因此我们只需要考虑枚举其质因子即可
复杂度(O(n log w))
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 using namespace std; 8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 9 ll fastpow(ll a,ll p,ll mod) 10 { 11 ll ans=1; 12 while(p) 13 { 14 if(p&1)ans=ans*a%mod; 15 a=a*a%mod;p>>=1; 16 } 17 return ans; 18 } 19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 20 #define maxn 1000005 21 int n; 22 ll tot,a[maxn],ans; 23 ll b[maxn],c[maxn]; 24 void check(ll k) 25 { 26 ll res=0,tt=0; 27 vector<pll> v; 28 for(int i=1;i<=n;++i)b[i]=a[i]%k,tt+=b[i],c[i]=b[i]; 29 ll K=tt/k; 30 int j=1; 31 for(int i=1;i<=K;++i) 32 { 33 v.clear(); 34 ll sx=0,sy=0,num=0; 35 while(j<=n&&num<=k) 36 { 37 if(b[j]>0) 38 { 39 ll tmp=min(b[j],k-num); 40 v.push_back(mpr(j,tmp)),sy+=j*tmp,num+=tmp; 41 b[j]-=tmp; 42 } 43 if(num==k)break; 44 j++; 45 } 46 ll t=(ll)5e18; 47 if(v.size()) 48 { 49 ll s=0; 50 for(int p=0;p<v.size();++p) 51 { 52 ll pos=v[p].first; 53 t=min(t,1ll*pos*s-sx+sy-1ll*(k-s)*pos); 54 sx+=pos*v[p].second;sy-=pos*v[p].second; 55 s+=v[p].second; 56 } 57 res+=t; 58 } 59 } 60 ans=min(ans,res); 61 } 62 int main() 63 { 64 scanf("%d",&n); 65 for(int i=1;i<=n;++i)scanf("%I64d",&a[i]),tot+=a[i]; 66 if(tot==1) 67 { 68 puts("-1"); 69 return 0; 70 } 71 ans=(ll)5e18; 72 ll x=tot; 73 for(ll i=2;i*i<=tot;++i)if(x%i==0) 74 { 75 while(x%i==0)x/=i; 76 check(i); 77 } 78 if(x>1)check(x); 79 cout<<ans<<endl; 80 }
C.
固定1,2两个点,然后利用(n)次叉积问出其他点在((1,2))这条线的哪一侧
然后再用(n)次面积问出两边最大面积点
最后问每个点在最大面积点的哪边,然后sort一下就可以了
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 int n; 5 vector<ll> A,B; 6 ll s[1005]; 7 vector<ll> X,Y,Z,W; 8 ll ask(ll t,ll i,ll j,ll k) 9 { 10 ll x; 11 cout<<t<<" "<<i<<" "<<j<<" "<<k<<endl; 12 fflush(stdout); 13 cin>>x; 14 return x; 15 } 16 bool cmp1(int x,int y) 17 { 18 return s[x]<s[y]; 19 } 20 bool cmp2(int x,int y) 21 { 22 return s[x]>s[y]; 23 } 24 int main() 25 { 26 cin>>n; 27 for(int i=3;i<=n;++i) 28 { 29 ll x=ask(2,1,i,2); 30 if(x>0)A.push_back(i); 31 else B.push_back(i); 32 } 33 ll ida=0,sa=0,idb=0,sb=0; 34 for(ll x:A) 35 { 36 ll y=ask(1,1,x,2); 37 s[x]=y; 38 if(y>sa)ida=x,sa=y; 39 } 40 for(ll x:B) 41 { 42 ll y=ask(1,1,x,2); 43 s[x]=y; 44 if(y>sb)idb=x,sb=y; 45 } 46 for(ll x:A)if(x!=ida) 47 { 48 ll y=ask(2,1,x,ida); 49 if(y<0)Y.push_back(x); 50 else X.push_back(x); 51 } 52 for(ll x:B)if(x!=idb) 53 { 54 ll y=ask(2,1,x,idb); 55 if(y<0)W.push_back(x); 56 else Z.push_back(x); 57 } 58 sort(X.begin(),X.end(),cmp1); 59 sort(Y.begin(),Y.end(),cmp2); 60 sort(Z.begin(),Z.end(),cmp1); 61 sort(W.begin(),W.end(),cmp2); 62 cout<<0<<" "; 63 cout<<1<<" "; 64 for(ll x:X)cout<<x<<" "; 65 if(ida)cout<<ida<<" "; 66 for(ll x:Y)cout<<x<<" "; 67 cout<<2<<" "; 68 for(ll x:Z)cout<<x<<" "; 69 if(idb)cout<<idb<<" "; 70 for(ll x:W)cout<<x<<" "; 71 }
D.
考虑一种暴力做法:
对于修改操作,对点(u)枚举和他相邻的点(v),那么就是这个子树(subtree(v))加(frac{(n-size[v])}{n}*d)
然后我们考虑提出根之后就是dfs序上一段区间加,可以线段树维护
但是这个在点度数大的时候会GG
那么考虑Bigsmall
把大度数的点当做关键点,这些点不用线段树维护,暴力打标记
然后暴力爬关键点统计标记
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define pii pair<int,int> 5 #define pll pair<long long,long long> 6 #define mpr(a,b) make_pair(a,b) 7 #define maxn 300005 8 using namespace std; 9 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);} 10 ll fastpow(ll a,ll p,ll mod) 11 { 12 ll ans=1; 13 while(p) 14 { 15 if(p&1)ans=ans*a%mod; 16 a=a*a%mod;p>>=1; 17 } 18 return ans; 19 } 20 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 21 const ll mod = 998244353; 22 int n,q; 23 vector<int> g[maxn]; 24 int f[maxn],top[maxn]; 25 int lpos[maxn],rpos[maxn],cnt,sz[maxn]; 26 ll addt[maxn]; 27 const int B = 100; 28 void dfs(int u,int fa) 29 { 30 if(g[fa].size()>B)top[u]=u; 31 else top[u]=top[fa]; 32 f[u]=fa; 33 lpos[u]=++cnt; 34 sz[u]=1; 35 for(int v:g[u])if(v!=fa) 36 { 37 dfs(v,u); 38 sz[u]+=sz[v]; 39 } 40 rpos[u]=cnt; 41 } 42 ll val[maxn<<2]; 43 void add(int rt,int l,int r,int ql,int qr,ll v) 44 { 45 if(ql>qr)return; 46 if(ql<=l&&r<=qr) 47 { 48 val[rt]=(val[rt]+v)%mod; 49 return; 50 } 51 int mid=(l+r)>>1; 52 if(ql<=mid)add(rt<<1,l,mid,ql,qr,v); 53 if(qr>mid)add(rt<<1|1,mid+1,r,ql,qr,v); 54 } 55 ll query(int rt,int l,int r,int pos) 56 { 57 ll ans=val[rt]; 58 int mid=(l+r)>>1; 59 if(l==r)return ans; 60 if(pos<=mid)ans=(ans+query(rt<<1,l,mid,pos))%mod; 61 else ans=(ans+query(rt<<1|1,mid+1,r,pos))%mod; 62 return ans; 63 } 64 int main() 65 { 66 scanf("%d%d",&n,&q); 67 for(int x,y,i=1;i<n;++i) 68 { 69 scanf("%d%d",&x,&y); 70 g[x].push_back(y); 71 g[y].push_back(x); 72 } 73 dfs(1,0); 74 while(q--) 75 { 76 int opt,u,d; 77 scanf("%d",&opt); 78 if(opt==1) 79 { 80 scanf("%d%d",&u,&d); 81 add(1,1,n,1,lpos[u]-1,1ll*sz[u]*inv(n,mod)%mod*d%mod); 82 add(1,1,n,rpos[u]+1,n,1ll*sz[u]*inv(n,mod)%mod*d%mod); 83 if(g[u].size()>B)addt[u]=(addt[u]+d)%mod; 84 else 85 { 86 for(int v:g[u])if(v!=f[u]) 87 { 88 add(1,1,n,lpos[v],rpos[v],1ll*(n-sz[v])*inv(n,mod)%mod*d%mod); 89 } 90 add(1,1,n,lpos[u],lpos[u],d); 91 } 92 } 93 else 94 { 95 scanf("%d",&u); 96 ll ans=(addt[u]+query(1,1,n,lpos[u]))%mod; 97 while(top[u]) 98 { 99 u=top[u]; 100 ans=(ans+1ll*(n-sz[u])*inv(n,mod)%mod*addt[f[u]]%mod)%mod; 101 u=f[u]; 102 } 103 printf("%I64d ",ans); 104 } 105 } 106 }