zoukankan      html  css  js  c++  java
  • Helvetic Coding Contest 2019

    题目链接:戳我

    小注:其中部分(大括号不换行的)代码是BLUESKY007神仙写的。

    CF1184 A1

    直接枚举,以根号的时间复杂度判断即可。注意x,y都是正整数。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    #define ll long long
    using namespace std;
    ll r;
    inline ll calc(ll x)
    {
        ll cur=r-x*x-x-1;
        if(cur<=0) return -1;
        if(cur%(2*x)==0) return cur/(2*x);
        else return -1;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%lld",&r);
        for(ll i=1;i<=1000000;i++)
        {
            if(calc(i)>0) 
            {
                printf("%lld %lld
    ",i,calc(i));
                return 0;
            }
        }
        printf("NO
    ");
        return 0;
    }
    

    CF1184 A2

    我们可以知道对于k,如果(gcd(k,n))可以的话,那么k一定也可以。
    所以我们就把枚举k才能计算的东西降低到了log的时间复杂度。
    然后按每次长度为k在环上往后跳,直到跳到一个点第二次。在这期间,显然其中为1的边的个数为偶数才是可行方案。
    那么直接把它们异或起来就行了。QAQ

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 200010
    using namespace std;
    int n,ans;
    int cnt[MAXN],done[MAXN];
    char s[MAXN];
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        scanf("%s",s);
        for(int i=1;i<=n;i++) cnt[__gcd(i,n)]++;
        for(int i=1;i<=n;i++)
        {
            if(cnt[i])
            {
                bool flag=false;
                memset(done,0,sizeof(done));
                for(int j=0;j<n;j++)
                {
                    if(!done[j])
                    {
                        int cur_ans=0,x=j;
                        while(!done[x])
                        {
                            cur_ans^=(s[x]-'0');
                            done[x]=1;
                            x=(x+i)%n;
                        }
                        if(cur_ans) flag=true;
                    }
                }
                if(!flag) ans+=cnt[i];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    

    CF1184 B1

    二分。

    #include<bits/stdc++.h>
     
    using namespace std;
     
    const int N=1e5+5;
     
    struct base{
    	int d,g,id;
    	bool operator<(const base&rhs)const{
    		return d!=rhs.d?d<rhs.d:id<rhs.id;
    	}
    }ba[N];
     
    int s,b,a[N];
     
    long long sum[N];
     
    int bs(int l,int r,int u){
    	if(l==r){
    		return l;
    	}
    	int mid=(l+r+1)>>1;
    	if(ba[mid].d<=u){
    		return bs(mid,r,u);
    	}
    	else{
    		return bs(l,mid-1,u);
    	}
    }
     
    int main(){
    	scanf("%d%d",&s,&b);
    	for(int i=1;i<=s;i++){
    		scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=b;i++){
    		scanf("%d%d",&ba[i].d,&ba[i].g);
    		ba[i].id=i;
    	}
    	sort(ba+1,ba+b+1);
    	for(int i=1;i<=b;i++){
    		sum[i]=sum[i-1]+ba[i].g;
    	}
    	for(int i=1;i<=s;i++){
    		printf("%lld%c",sum[bs(0,b,a[i])]," 
    "[i==s]);
    	}
    	return 0;
    }
    

    CF1184 B2

    CF1184 C1

    暴力地找四个点,然后判断一下他们构成的矩形上是不是正好缺少一个点qwq

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    using namespace std;
    int n;
    struct Node{int x,y;}node[MAXN];
    inline void calc(int a,int b,int c,int d)
    {
        int down=0x3f3f3f3f,up=0,ll=0x3f3f3f3f,rr=0,cnt=0;
        ll=min(ll,node[a].x),ll=min(ll,node[b].x),ll=min(ll,node[c].x),ll=min(ll,node[d].x);
        rr=max(rr,node[a].x),rr=max(rr,node[b].x),rr=max(rr,node[c].x),rr=max(rr,node[d].x);
        down=min(down,node[a].y),down=min(down,node[b].y),down=min(down,node[c].y),down=min(down,node[d].y);
        up=max(up,node[a].y),up=max(up,node[b].y),up=max(up,node[c].y),up=max(up,node[d].y);
        int kkk;
        for(int i=1;i<=n;i++)
        {
            if(ll<=node[i].x&&node[i].x<=rr&&(node[i].y==down||node[i].y==up)) cnt++;
            else if(down<=node[i].y&&node[i].y<=up&&(node[i].x==ll||node[i].x==rr)) cnt++;
            else kkk=i;
        }
        if(cnt==n-1) 
        {
            printf("%d %d
    ",node[kkk].x,node[kkk].y);
            exit(0);
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        for(int i=1;i<=4*n+1;i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
        }
        n=4*n+1;
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                for(int k=j+1;k<=n;k++)
                    for(int p=k+1;p<=n;p++)
                        calc(i,j,k,p);
        return 0;
    }
    

    CF1184 C2

    CF1184 D1

    开始还以为要用链表直接模拟即可,注意判断一下加入和删除的位置和当前主人公所在位置的大小。

    
     #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    #define ll long long
    using namespace std;
    int n,m,k,t;
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d%d%d",&n,&k,&m,&t);
        while(t--)
        {
            int op,pos;
            scanf("%d%d",&op,&pos);
            if(op==0)
            {
                if(pos>=k) n=pos;
                else n-=pos,k-=pos;
            }
            else
            {
                if(pos<=k) k++,n++;
                else n++;
            }
            printf("%d %d
    ",n,k);
        }
        return 0;
    }
    

    CF1184 E1

    二分一下桥1的值,看看能否在最小生成树中。

    #include<bits/stdc++.h>
     
    using namespace std;
     
    const int N=1e6+6;
     
    int n,m,fr[N],to[N],w[N],fa[N],siz[N];
     
    bool usd[N];
     
    int find(int u){
    	return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
    }
     
    struct edge{
    	int u,v,w,id;
    	bool operator<(const edge&rhs)const{
    		return w<rhs.w;
    	}
    }e[N];
     
    bool unifa(int u,int v){
    	if(find(u)==find(v)){
    		return 0;
    	}
    	fa[find(v)]=find(u);
    	return 1;
    }
     
    bool can(int u){
    	for(int i=1;i<=n;i++){
    		fa[i]=i;
    	}
    	for(int i=2;i<=m;i++){
    		if(e[i].w<u){
    			unifa(e[i].u,e[i].v);
    		}
    	}
    	return unifa(e[1].u,e[1].v);
    }
     
    int bs(int l,int r){
    	if(l==r){
    		return l;
    	}
    	int mid=(l+r+1)>>1;
    	if(!can(mid)){
    		return bs(l,mid-1);
    	}
    	else{
    		return bs(mid,r);
    	}
    }
     
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    		e[i].id=i;
    	}
    	printf("%d
    ",bs(0,1e9));
    	return 0;
    }
    

    CF1184 E2

    我们先构建最小生成树,然后每次处理到一条不在最小生成树上的边的时候,倍增往上面找最小的一条边的值就行了。

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define mk make_pair
    #define fi first
    #define se second
    #define debug printf("%d %s
    ",__LINE__,__FUNCTION__)
     
    using namespace std;
     
    const int N=1e6+6;
     
    int n,m,fa[N],dep[N];
     
    vector<int>G[N],W[N];
     
    bool vis[N];int ans[N];
     
    int find(int u){
    	return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
    }
     
    bool unifa(int u,int v){
    	if(find(u)==find(v)){
    		return 0;
    	}
    	fa[find(v)]=find(u);
    	return 1;
    }
     
    struct edge{
    	int u,v,w,id;
    	edge(int ru=0,int rv=0,int rw=0,int ri=0){
    		u=ru;v=rv;w=rw;id=ri;
    	}
    	bool operator<(const edge&rhs)const{
    		return w<rhs.w;
    	}
    }e[N];
     
    void addedge(int u,int v,int w){
    	G[u].push_back(v);W[u].push_back(w);
    }
     
    int jump[N][18],mx[N][18];
     
    void dfs(int u,int fr){
    	for(int i=0,v;i<(int)G[u].size();i++){
    		v=G[u][i];
    		if(v==fr){
    			continue;
    		}
    		dep[v]=dep[u]+1;
    		jump[v][0]=u;
    		mx[v][0]=W[u][i];
    		for(int j=1;j<18;j++){
    			jump[v][j]=jump[jump[v][j-1]][j-1];
    			mx[v][j]=max(mx[v][j-1],mx[jump[v][j-1]][j-1]);
    		}
    		dfs(v,u);
    	}
    }
     
    pii lca(int u,int v){
    	int rep=0;
    	if(dep[u]<dep[v]){
    		swap(u,v);
    	}
    	for(int i=17;~i;i--){
    		if(dep[jump[u][i]]>=dep[v]){
    			rep=max(mx[u][i],rep);
    			u=jump[u][i];
    		}
    	}
    	if(u==v){
    		return mk(u,rep);
    	}
    	for(int i=17;~i;i--){
    		if(jump[u][i]!=jump[v][i]){
    			rep=max(rep,max(mx[u][i],mx[v][i]));
    			u=jump[u][i];
    			v=jump[v][i];
    		}
    	}
    	rep=max(rep,max(mx[u][0],mx[v][0]));
    	return mk(jump[u][0],rep);
    }
     
    int query(int u,int v){
    	return lca(u,v).se;
    }
     
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1,u,v,w;i<=m;i++){
    		scanf("%d%d%d",&u,&v,&w);
    		e[i]=edge(u,v,w,i);
    	}
    	for(int i=1;i<=n;i++){
    		fa[i]=i;
    	}
    	sort(e+1,e+m+1);
    	for(int i=1;i<=m;i++){
    		if(unifa(e[i].u,e[i].v)){
    			vis[e[i].id]=1;
    			addedge(e[i].u,e[i].v,e[i].w);
    			addedge(e[i].v,e[i].u,e[i].w);
    		}
    	}
    	dep[1]=1;dfs(1,0);
    	for(int i=1;i<=m;i++){
    		if(!vis[e[i].id]){
    			ans[e[i].id]=query(e[i].u,e[i].v);
    		}
    	}
    	for(int i=1;i<=m;i++){
    		if(!vis[i]){
    			printf("%d
    ",ans[i]);
    		}
    	}
    	return 0;
    }
    

    CF1184 E3

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define mk make_pair
    #define fi first
    #define se second
     
    using namespace std;
     
    const int N=1e6+6;
     
    int n,m,fa[N],afa[N],dep[N],eid[N];
     
    vector<int>G[N],W[N],wid[N];
     
    bool vis[N];int ans[N];
     
    int find(int u){
    	return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
    }
     
    bool unifa(int u,int v){
    	if(find(u)==find(v)){
    		return 0;
    	}
    	fa[find(v)]=find(u);
    	return 1;
    }
     
    int afind(int u){
    	return afa[u]==u?afa[u]:afa[u]=afind(afa[u]);
    }
     
    bool aunifa(int u,int v){
    	if(afind(u)==afind(v)){
    		return 0;
    	}
    	afa[afind(u)]=afind(v);
    	return 1;
    }
     
    struct edge{
    	int u,v,w,id;
    	edge(int ru=0,int rv=0,int rw=0,int ri=0){
    		u=ru;v=rv;w=rw;id=ri;
    	}
    	bool operator<(const edge&rhs)const{
    		return w<rhs.w;
    	}
    }e[N];
     
    void addedge(int u,int v,int w,int id){
    	G[u].push_back(v);W[u].push_back(w);wid[u].push_back(id);
    }
     
    int jump[N][18],mx[N][18];
     
    void dfs(int u,int fr){
    	for(int i=0,v;i<(int)G[u].size();i++){
    		v=G[u][i];
    		if(v==fr){
    			continue;
    		}
    		dep[v]=dep[u]+1;
    		jump[v][0]=u;
    		eid[v]=wid[u][i];
    		mx[v][0]=W[u][i];
    		for(int j=1;j<18;j++){
    			jump[v][j]=jump[jump[v][j-1]][j-1];
    			mx[v][j]=max(mx[v][j-1],mx[jump[v][j-1]][j-1]);
    		}
    		dfs(v,u);
    	}
    }
     
    pii lca(int u,int v){
    	int rep=0;
    	if(dep[u]<dep[v]){
    		swap(u,v);
    	}
    	for(int i=17;~i;i--){
    		if(dep[jump[u][i]]>=dep[v]){
    			rep=max(mx[u][i],rep);
    			u=jump[u][i];
    		}
    	}
    	if(u==v){
    		return mk(u,rep);
    	}
    	for(int i=17;~i;i--){
    		if(jump[u][i]!=jump[v][i]){
    			rep=max(rep,max(mx[u][i],mx[v][i]));
    			u=jump[u][i];
    			v=jump[v][i];
    		}
    	}
    	rep=max(rep,max(mx[u][0],mx[v][0]));
    	return mk(jump[u][0],rep);
    }
     
    int query(int u,int v){
    	return lca(u,v).se;
    }
     
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1,u,v,w;i<=m;i++){
    		scanf("%d%d%d",&u,&v,&w);
    		e[i]=edge(u,v,w,i);
    	}
    	for(int i=1;i<=n;i++){
    		fa[i]=afa[i]=i;ans[i]=1e9;
    	}
    	sort(e+1,e+m+1);
    	for(int i=1;i<=m;i++){
    		if(unifa(e[i].u,e[i].v)){
    			vis[e[i].id]=1;
    			addedge(e[i].u,e[i].v,e[i].w,e[i].id);
    			addedge(e[i].v,e[i].u,e[i].w,e[i].id);
    		}
    	}
    	dep[1]=1;dfs(1,0);
    	for(int i=1,l,u,v;i<=m;i++){
    		if(!vis[e[i].id]){
    			ans[e[i].id]=query(e[i].u,e[i].v);
    			l=lca(e[i].u,e[i].v).fi;
    			u=afind(e[i].u);v=afind(e[i].v);
    			while(dep[u]>dep[l]){
    				if(aunifa(u,jump[u][0])){
    					ans[eid[u]]=e[i].w;
    				}
    				u=afind(jump[u][0]);
    			}
    			while(dep[v]>dep[l]){
    				if(aunifa(v,jump[v][0])){
    					ans[eid[v]]=e[i].w;
    				}
    				v=afind(jump[v][0]);
    			}
    		}
    	}
    	for(int i=1;i<=m;i++){
    		printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++ 引用与常量
    树的三种存储方法
    二叉树 基本运算
    Win10阻止电脑关机时弹出正在关闭应用的方法及恢复
    使用spring+quartz配置多个定时任务(包括项目启动先执行一次,之后再间隔时间执行)
    MySQL为某数据库中所有的表添加相同的字段
    Mysql定时任务详情
    MYSQL存储过程即常用逻辑
    后台发送请求,HttpClient的post,get各种请求,带header的请求
    java后台发送请求获取数据,并解析json数据
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11148850.html
Copyright © 2011-2022 走看看