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:;
    } 
}
View Code

 

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");
        }
    }
}
View Code

 

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);
    }
}
View Code

 

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");
    }
}
View Code

 

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);
    }
}
View Code

 

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;
    }
}
View Code

 

posted @ 2021-01-27 20:50  Anonytt  阅读(116)  评论(0编辑  收藏  举报