A题:水。
/* ID: huanrui ke PROG: AIM Tech Round (Div. 2) LANG: C++ */ #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; double d,L,v1,v2; int main() { //freopen("in.txt","r",stdin); while(cin>>d>>L>>v1>>v2){ printf("%.7f\n",(L-d)/(v1+v2)); } return 0; }
B题:水。
/* ID: huanrui ke PROG: AIM Tech Round (Div. 2) LANG: C++ */ #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n,a[maxn]; map<ll,int> mp; int main() { //freopen("in.txt","r",stdin); while(cin>>n){ REP(i,1,n) scanf("%d",&a[i]); mp.clear(); sort(a+1,a+n+1); ll ans=0; for(int i=n;i>=1;i--){ if(mp[a[i]]){ while(a[i]>0&&mp[a[i]]) a[i]--; } ans+=a[i]; mp[a[i]]=1; } cout<<ans<<endl; } return 0; }
C题:直接判补图会简单一点,对补图用a-c染色,对于单独的点直接染为b,最后验证一下就可以了。
/* ID: huanrui ke PROG: AIM Tech Round (Div. 2) LANG: C++ */ #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=510; const int INF=1e9+10; int g[maxn][maxn]; int e[maxn][maxn]; int n,m; int u,v; int deg[maxn]; char vis[maxn]; void dfs(int u,char c) { vis[u]=c; for(int v=1;v<=n;v++){ if(vis[v]!='#') continue; if(!e[u][v]){ if(c=='a') dfs(v,'c'); else if(c=='c') dfs(v,'a'); } } } bool jud() { REP(i,1,n) REP(j,1,n) g[i][j]=1; REP(i,1,n){ REP(j,1,n){ if(i==j) continue; if(vis[i]=='a'&&vis[j]=='c') g[i][j]=0; if(vis[i]=='c'&&vis[j]=='a') g[i][j]=0; } } /* REP(i,1,n){ REP(j,1,n){ cout<<g[i][j]<<" "; } cout<<endl; } REP(i,1,n){ REP(j,1,n){ cout<<e[i][j]<<" "; } cout<<endl; } */ REP(i,1,n){ REP(j,1,n){ if(i==j) continue; if(e[i][j]!=g[i][j]) return 0; } } return 1; } int main() { //freopen("in.txt","r",stdin); while(cin>>n>>m){ MS0(e);MS0(deg);MS0(g); REP(i,1,m){ scanf("%d%d",&u,&v); e[u][v]=e[v][u]=1; } REP(i,1,n){ REP(j,1,n){ if(i==j) continue; if(!e[i][j]){ deg[i]++; } } } //REP(i,1,n) deg[i]/=2; //REP(i,1,n) cout<<deg[i]<<" ";cout<<endl; memset(vis,'#',sizeof(vis)); REP(i,1,n){ if(vis[i]!='#') continue; if(deg[i]>0){ dfs(i,'a'); } } REP(i,1,n) if(vis[i]=='#') vis[i]='b'; //REP(i,1,n) cout<<vis[i];cout<<endl; if(jud()){ puts("Yes"); REP(i,1,n) printf("%c",vis[i]); puts(""); } else puts("No"); } return 0; }
D题:
枚举出a[1],a[1]+1,a[1]-1,a[n],a[n]+1,a[n]-1的所有质因子,分别判断,然后预处理保留前缀f[i]和保留后缀g[j],代价就是f[i]+(j-i-1)*b+g[j]=(f[i]-(i+1)*b) + (g[j]+j*b) ,然后枚举i快速找到j就可以了。
复杂度o(n*质因子个数)=o(n*log(1e9)) .
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; const ll MAX=1e18+10; int n;ll a,b; ll x[maxn]; ll f[maxn],g[maxn]; vector<ll> prime; bool isprime[maxn]; set<ll> s; void getPrime() { memset(isprime,1,sizeof(isprime)); isprime[1]=0; REP(i,2,maxn-1){ if(!isprime[i]) continue; for(int j=i+i;j<maxn;j+=i) isprime[j]=0; } REP(i,2,maxn-1) if(isprime[i]) prime.push_back(i); //for(int i=0;i<10;i++) cout<<prime[i]<<" ";cout<<endl; } ll change(ll x,ll p) { if(x%p==0) return 0; if((x-1)%p==0||(x+1)%p==0) return b; return -1; } ll solve(ll p) { int L=n+1,R=0; f[0]=0; int tag=0; REP(i,1,n){ ll t=change(x[i],p); if(t==-1){ L=i;tag=1; } if(tag) f[i]=MAX; else f[i]=f[i-1]+t; } g[n+1]=0; tag=0; for(int i=n;i>=1;i--){ ll t=change(x[i],p); if(t==-1){ R=i;tag=1; } if(tag) g[i]=MAX; else g[i]=g[i+1]+t; } /// f[i] + (j-i-1)*b + g[j] ///= f[i] + g[j]+j*b - (i+1)*b ///= ( f[i]-(i+1)*b ) + min( g[j]+j*b [j=i+1~n] ) ll G=g[n+1]+(n+1)*a; ll res=f[n]; for(int i=n;i>=0;i--){ res=min(res,f[i]-(i+1)*a+G); G=min(G,g[i]+i*a); } return res; } void get(ll x) { if(x==0||x==1) return; for(int i=0;i<prime.size();i++){ ll t=prime[i]; if(t*t>x) break; if(x%t==0){ s.insert(t); while(x%t==0) x/=t; } } if(x>1) s.insert(x); } void Init() { s.clear(); get(x[1]);get(x[1]+1);get(x[1]-1); get(x[n]);get(x[n]+1);get(x[n]-1); //for(set<ll>::iterator it=s.begin();it!=s.end();++it) cout<<(*it)<<" ";cout<<endl; } int main() { freopen("in.txt","r",stdin); getPrime(); while(cin>>n>>a>>b){ REP(i,1,n) scanf("%I64d",&x[i]); Init(); ll ans=MAX; for(set<ll>::iterator it=s.begin();it!=s.end();++it){ ans=min(ans,solve(*it)); } cout<<ans<<endl; } return 0; }