HDU多校 1、2
G1
D
可以看出,到了>3的情况,只要abcabc循环下去就行。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 5e4+10; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} int t,n; int main() { t=read(); while (t--) { n=read(); if (n==1) cout<<26<<endl; else if (n==2) cout<<676<<endl; else if (n==3) cout<<676*26<<endl; else cout<<26*25*24%mod<<endl;; } return 0; }
I
这题本意跟栈的处理基本上是相同了,栈模拟即可。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 5e4+10; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { ll p,a; }; ll T,i,n,ans,num; node b[maxn],s[maxn]; bool cmp(node x,node y) { if (x.a==y.a) return x.p<y.p; return x.a<y.a; } bool check(node x,node y,node z) { return (y.p-z.p)*(y.a-x.a)-(z.a-y.a)*(x.p-y.p)<=0; } int main() { T=read(); while (T--) { n=read(); map<pii , ll> mapp; for (i=1;i<=n;i++) { b[i].p=read(),b[i].a=read(); mapp[mp(b[i].p,b[i].a)]++; } sort(b+1,b+1+n,cmp); num=0; for (i=1;i<=n;i++) { while ((num>0 && (b[i].p>=s[num].p)) ||(num>1 && check(s[num-1],s[num],b[i]))) { num--; } s[++num]=b[i]; } ans=num; for (i=1;i<=num;i++) { if (mapp[mp(s[i].p,s[i].a)]>1) ans--; } cout<<ans<<endl; } return 0; } //18 //24163 1 //24068 190 //23783 380 //23308 570 //22643 760 //21788 950 //20743 1140 //19508 1330 //18083 1520 //16468 1710 //14663 1900 //12668 2090 //10483 2280 //8108 2470 //5543 2660 //2788 2850 //24168 27 //24172 26
G2
A
题意就是把连通块进行不断拆分删边,根本没意识到这就是并查集的逆过程……
逆向思维很重要
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5+7; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { ll value,num; }; vector <ll> G[maxn]; node a[maxn]; ll father[maxn],u,v,i,n,m,t,vis[maxn]; ll sum,block; bool cmp(node x,node y) { return x.value>y.value; } ll fa(ll x) { return father[x]==x?x:father[x]=fa(father[x]); } ll join(ll x, ll y) { x=fa(x),y=fa(y); if (x!=y) father[x]=y; } int main() { t=read(); while (t--) { n=read(),m=read(); for (i=1;i<=n;i++) father[i]=i,a[i].num=i,a[i].value=read(); sort(a+1,a+1+n,cmp); a[n+1].value=0; for (i=1;i<=m;i++) { u=read(),v=read(); G[u].push_back(v); G[v].push_back(u); } for (i=1;i<=n;i++) vis[i]=false; sum=block=0; for (i=1;i<=n;i++) { u=a[i].num; vis[u]=true; block++; for (auto v:G[u]) { if (!vis[v]) continue; if (fa(v)!=fa(u)) join(u,v),block--; } sum+=block*(a[i].value-a[i+1].value); } for (i=1;i<=n;i++) G[i].clear(); cout<<sum<<endl; } return 0; }
J
数据很小,暴搜即可。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 55; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { ll a,b,c,d; }; vector <node> G[maxn]; int i,n,k,vis[maxn],t,x,a,b,c,d; ll cnt; ll dfs(ll num,ll a,ll b,ll c,ll d) { if (num==cnt+1) { return (100+a)*(100+b)*(100+c)*(100+d); } ll ans=0; for (ri i=0;i<G[num].size();i++) { node now=G[num][i]; ans=max(ans,dfs(num+1,a+now.a,b+now.b,c+now.c,d+now.d)); } return ans; } int main() { t=read(); while (t--) { n=read(),k=read(); cnt=0; for (i=1;i<=n;i++) { x=read(),a=read(),b=read(); c=read(),d=read(); if (!vis[x]) { vis[x]=++cnt; } G[vis[x]].push_back({a,b,c,d}); } printf("%lld\n",dfs(1,0,0,0,0)); for (i=1;i<=n;i++) G[i].clear(),vis[i]=0; } return 0; }
F
将某一位从1变成0,其实就是从原数中减去那一位的斐波那契数。
然后可以得出下面的式子,假设改变位的下标为k,则有:
A * B = C + Fk
容易得到ABC都是可以O(n)算出来的,最后的Fk暴力枚举也能求出来。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 2e6+7; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll f[maxn],i,t,x,n,sum1,sum2,sum3; int main() { f[1]=1,f[2]=2; for (i=3;i<=maxn;i++) f[i]=f[i-1]+f[i-2]; t=read(); while (t--) { n=read(); sum1=sum2=sum3=0; for (i=1;i<=n;i++) { x=read(); if (x==1) sum1+=f[i]; } n=read(); for (i=1;i<=n;i++) { x=read(); if (x==1) sum2+=f[i]; } n=read(); for (i=1;i<=n;i++) { x=read(); if (x==1) sum3+=f[i]; } for (i=1;i<=maxn;i++) { if (sum3==sum1*sum2-f[i]) { cout<<i<<endl; break; } } } return 0; }
总结:有些题目很多人过,比如G1的Fibonacci Sum,但是补过很长时间真就是这没学,那不懂,况且我无法保证比赛时能否做的出来这种烧脑的题目,以至于这些数论题就此作罢。