2016ACM-ICPC亚洲区域赛(大连)
通过:A.D.F.H.I.J
A:Wrestling Match
Editorial:用二分图来做,以好人坏人开始各做一次bfs,遇到冲突就直接结束,最后再把m组数据里没有vis过的跑bfs,最后再特判是否还有没有vis过的,如果还存在就输出NO
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int tot,head[maxn]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n,m,x,y,col[maxn],vis[maxn]; int main(){ while(~scanf("%d%d%d%d",&n,&m,&x,&y)){ tot=0;rep(i,0,n) head[i]=-1,vis[i]=0,col[i]=0; vector<int> good,bad;set<int> s; rep(i,1,m){ int u,v;scanf("%d%d",&u,&v); add(u,v);add(v,u); s.insert(u);s.insert(v); } rep(i,1,x){ int p;scanf("%d",&p); good.pb(p);col[i]=1; } rep(i,1,y){ int p;scanf("%d",&p); bad.pb(p);col[i]=2; } int flag=0; for(auto it:good){ if(!vis[it]){ vis[it]=1; queue<int> q;q.push(it); while(!q.empty()){ int now=q.front();q.pop();vis[now]=1; for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(col[v]==col[now]){ flag=1; puts("NO"); goto end; break; } else if(!vis[v]){ col[v]=3-col[now]; vis[v]=1;q.push(v); } } } } } for(auto it:bad){ if(!vis[it]){ vis[it]=1;queue<int> q;q.push(it); while(!q.empty()){ int now=q.front();q.pop();vis[now]=1; for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(col[v]==col[now]){ flag=1; puts("NO"); goto end; break; } else if(!vis[v]){ col[v]=3-col[now]; vis[v]=1;q.push(v); } } } } } for(auto it:s){ if(!vis[it]){ col[it]=1;vis[it]=1; queue<int> q;q.push(it); while(!q.empty()){ int now=q.front();q.pop();vis[now]=1; for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(col[v]==col[now]){ flag=1; puts("NO"); goto end; break; } else if(!vis[v]){ col[v]=3-col[now]; vis[v]=1;q.push(v); } } } } } rep(i,1,n){ if(!vis[i]){ flag=1; puts("NO"); goto end; break; } } if(!flag) puts("YES"); end:; } }
D:A Simple Math Problem
Editorial:首先分析数据范围,可以得知需要用O(logn)以下的时间复杂度处理每一组结果。
∵x*y/gcd(x,y)=b并且x+y=a,所以x*y=gcd(x,y)*b,y=a-x.
令k=gcd(x,y),则x=u*k,y=v*k;则a=(u+v)*k,b=(u*v)*k
gcd(x,y)=k说明gcd(u,v)=1即u,v互质。
那么我们要考虑gcd(a,b)的话其实就是考虑gcd(u+v,u*v)的结果
我们假设gcd(u+v,u*v)=t,即这里存在一个因子t,该因子属于u或者属于v,但因为u与v是互质的,所以该因子t必不可能同属于u与v。
又由于u与v必须同时存在因子t才能使u+v也存在因子t,
(这里再假设u=A*t,v=B*t,则u+v=(A+B)*t,要满足上面猜想的话必须u与v均为t的倍数才行。)
所以与之矛盾。故gcd(a,b)=gcd(x,y).
∴x*(a-x)=b*gcd(a,b)
移向可得:x^2-a*x+b*gcd(a,b)=0,然后求解就可以,记得特判delta和处理eps之间的关系。另外要记得输出的两个答案小的在前大的在后
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int main(){ int a,b; while(~scanf("%d%d",&a,&b)){ double delta=a*a-4*b*__gcd(a,b); if(delta<-eps){ puts("No Solution"); } else{ double x1=(a+sqrt(delta))*0.500,y1=a-x1; if(x1-floor(x1)<eps&&y1-floor(y1)<eps){ int qq=floor(x1),jj=floor(y1); printf("%d %d\n",min(qq,jj),max(qq,jj)); } else puts("No Solution"); } } }
F:Detachment
Editorial:和我出的新生赛的E题类似。用乘法逆元来做。先预处理前缀和(不需要取模)与前缀积,再二分查找最大值以让remain尽可能小。记得除法取模需要用逆元
(a/b)%mod=a*qp(b,mod-2,mod)%mod;
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; ll preji[maxn],prehe[maxn]; ll qp(ll a,ll b,ll c){ ll ans = 1; ll base = a%c; while(b){ if(b & 1) ans = (ans*base)%c; base = (base*base)%c; b >>= 1; } return ans; } int main(){ preji[1]=1;prehe[1]=0; rep(i,2,1e5){ preji[i]=preji[i-1]*i%mod; prehe[i]=prehe[i-1]+i; } int T;scanf("%d",&T); while(T--){ ll n;scanf("%lld",&n); if(n==1){puts("1");continue;} ll ans=0; ll k=upper_bound(prehe+1,prehe+100000+1,n)-prehe-1; ll remain=n-prehe[k]; if(remain==0){ ans=preji[k]; } else if(remain<k&&remain>0){ ans=preji[k+1]*qp(k-remain+1,mod-2,mod)%mod; } else if(remain==k){ ans=preji[k]*qp(2,mod-2,mod)%mod*(k+2)%mod; } printf("%lld\n",ans); } }
H:To begin or not to begin
Editorial:经过分析发现怎么要都不可能后手占优势,特判奇偶就行
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int main(){ int k; while(~scanf("%d",&k)){ if(k%2==1) puts("0"); else puts("1"); } }
I:Convex
Editorial:简单的计算几何
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; const double pi = 3.141592654; int main(){ int n, d; while(cin >> n >> d){ double ans = 0.0; for(int i = 1; i <= n; i++){ int x; cin >> x; ans += 0.5 * d * d * sin(x * pi / 180.0); } printf("%.3lf\n", ans); } }
J:Find Small A
Editorial:每次比较后八位是否为97,如果是则ans++,然后不断移8位直到不能移动。
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; ll a[maxn]; int main(){ int n; while(~scanf("%d",&n)){ rep(i,1,n) scanf("%lld",&a[i]); int cnt=0; rep(i,1,n){ while(a[i]>0){ if((a[i]&255)==97) ++cnt; a[i]>>=8; } } cout<<cnt<<endl; } }