zoukankan      html  css  js  c++  java
  • [20181107][模拟赛]

    题面

    T1

    思路

    考虑一下每个数会与其他位置的哪些数字遇到。显然每隔gcd(n,m,k)个数都会遇到一次。所以只要看一下将给出的所有数字全部对gcd(n,m,k)取模是否能包含从0到gcd(n,m,k) - 1的所有数就行了。

    代码

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 100000 + 100;
    ll read() {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0';
    		c = getchar();
    	}
    	return x * f;
    }
    int n,m,K,a[N],b[N],k[N];
    int gcd(int x,int y) {
    	return !y ? x : gcd(y,x % y);
    }
    namespace BF1 {
    	
    	void Main() {
    		memset(a,0,sizeof(a));
    		memset(b,0,sizeof(b));
    		int aa = read();
    		for(int i = 1;i <= aa;++i) a[read()] = 1;
    		int bb = read();
    		for(int i = 1;i <= bb;++i) b[read()] = 1;
    		read();
    		for(int i = 0;i <= 100000;++i) {
    			int x1 = i % n, x2 = i % m;
    			a[x1] = b[x2] = a[x1] | b[x2];
    		}
    		for(int i = 0;i < n;++i) {
    			if(a[i] != 1) {
    				puts("No");
    				return;
    			}
    		}
    		for(int i = 0;i < m;++i) {
    			if(b[i] != 1) {
    				puts("No");
    				return;
    			}
    		}
    		puts("Yes");
    	}
    }
    namespace BF2 {
    	int tmp[N * 5],js = 0;
    	void Main() {
    		js = 0;
    		int mod = gcd(gcd(n,m),K);
    		int aa = read();
    		for(int i = 1;i <= aa;++i) tmp[++js] = read() % mod;
    		int bb = read();
    		for(int i = 1;i <= bb;++i) tmp[++js] = read() % mod;
    		int kk = read();
    		for(int i = 1;i <= kk;++i) tmp[++js] = read() % mod;
    		int now = 0;
    		sort(tmp + 1,tmp + js + 1); 
    		tmp[0] = -1;
    		int ans = 0;
    		for(int i = 1;i <= js;++i) {
    			if(tmp[i] == tmp[i-1]) continue;
    			if(tmp[i] == tmp[i-1]+1) now++;
    			else {
    				ans = max(ans,now);
    				now = 1;
    			}
    		}
    		ans = max(ans,now);
    		if(ans >= mod) puts("Yes");
    		else puts("No");
    		return;
    	}
    }
    int main() {
    	freopen("happy2.in","r",stdin);
    	freopen("happy2.out","w",stdout);
    	int T = read();
    	while(T--) {
    		n = read(),m = read(),K = read();
    		if(n <= 100 && m <= 100 && K == 0) {
    			BF1::Main();
    			continue;
    		}
    		BF2::Main();
    	}
    	return 0;
    }
    

    T2

    想了一会感觉不可做,直接55分暴力。

    55分代码

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    const int N = 300000 + 100;
    ll read() {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0';
    		c = getchar();
    	}
    	return x * f;
    }
    int n,p;
    namespace BF1 {
    	int du[N];
    	void Main() {
    		for(int i = 1;i <= n;++i) {
    			int x = read(), y = read();
    			du[x]++;
    			du[y]++;
    		}
    		ll ans1 = 0;
    		for(int i = 1;i <= n;++i)
    			if(du[i] == 0) ans1++;
    		cout<<(ll)n * (ll)(n - 1)/2 - (ans1 * (ans1 - 1) / 2);
    		return;
    	}
    }
    namespace BF2 {
    	const int NN = 110;
    	bitset <NN> tmp[NN];
    	int ans = 0;
    	inline int check(int x,int y) {
    		bitset <NN> ls;
    		ls = tmp[x] | tmp[y];
    		return ls.count() >= p;
    	}
    	void Main() {
    		for(int i = 1;i <= n;++i) {
    			int x = read(),y = read();
    			tmp[x][i] = 1;
    			tmp[y][i] = 1;
    		}
    		for(int i = 1;i <= n;++i) {
    			for(int j = i + 1;j <= n;++j) {
    				ans += check(i,j);
    			}
    		}
    		cout<<ans<<endl;
    	}
    }
    int main() {
    	freopen("suspect.in","r",stdin);
    	freopen("suspect.out","w",stdout);
    	n =  read(),p = read();
    	if(p == 0) {
    		cout<<((ll)n*(n-1) / 2);
    		return 0;
    	}
    	if(p == 1) {
    		BF1::Main();
    		return 0;
    	}
    	if(n <= 100) {
    		BF2::Main();
    		return 0;
    	}
    	return 0;
    }
    

    std

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<cstdlib>
    #define INF 100000000
    using namespace std;
    typedef long long LL;
    struct Edge
    {
        int from,to,pre;
    }e[1000000];
    int h[300005]={0},cou=0;
    int c[300005],ed[300005];
    void Addedge(int from,int to)
    {
        cou++;
        e[cou]=((Edge){from,to,h[from]});
        h[from]=cou;
    }
    
    inline void update(int x)
    {
        if(x==0)
        {
            c[0]++;
            return;
        }
        for(;x<=300000;x+=x&-x)
            c[x]++;
    }
    inline int get(int x)
    {
        if(x==-1) return 0;
        int sum=0;
        for(;x;x-=x&-x)
            sum+=c[x];
        return sum+c[0];
    }
    int main()
    {
        freopen("suspect.in","r",stdin);
        freopen("suspect.out","w",stdout);
        LL ans=0;
        int sum,i,n,p,a,b,v,j;
        cin>>n>>p;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            Addedge(a,b); Addedge(b,a);
            ed[a]++; ed[b]++;
        }
        for(i=1;i<=n;i++)
            update(ed[i]);
        for(i=1;i<=n;i++)
        {
            if(ed[i]>=p)
                ans+=n-1;
            else
            {
                sum=n-get(p-ed[i]-1);
                if(ed[i]>=p-ed[i]) sum--;
                for(j=h[i];j;j=e[j].pre)
                {
                    v=e[j].to;
                    if(ed[v]==p-ed[i]) sum--;
                    ed[v]--;
                }
                for(j=h[i];j;j=e[j].pre)
                {
                    v=e[j].to;
                    ed[v]++;
                }
                ans+=sum;
            }
        }
        cout<<ans/2<<endl;
        return 0;
    }
    

    T3

    80分思路

    暴力分感觉都可做,然后就写了80分暴力。用莫队卡一下100分???会TLE吧(真麻烦,不想写)。

    100分思路

    如果这个题让着求区间出现奇数次的数的异或和就很简单了。所以我们可以对于询问先离线一下。按照右端点拍个序。然后用树状数组维护一下区间异或和。就是从1扫到n,同时将当前的数上一次出现的位置(在树状数组里)异或上这个数。然后查询就好了。

    100分代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<cstdlib>
    #include<string>
    #include<bitset>
    #include<iomanip>
    #include<deque>
    #include<utility>
    #define INF 1000000000
    #define fi first
    #define se second
    #define N 1000005
    #define P 1000000007
    #define debug(x) cerr<<#x<<"="<<x<<endl
    #define MP(x,y) make_pair(x,y)
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    int c[N],now,sum,a[N],b[N],ans[N],nxt[N],n;
    map<int,int> vis,pre;
    vector<pii> Q[N];
    
    void Add(int x,int w)
    {
        for(;x<=n;x+=x&-x)
            c[x]^=w;
    }
    
    int Get(int x)
    {
        int s=0;
        for(;x;x-=x&-x)
            s^=c[x];
        return s;
    }
    
    int main()
    {
        int i,m,ql,qr,j;
        freopen("xor.in","r",stdin);
        freopen("xor.out","w",stdout);
        cin>>n;
        now=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            vis[a[i]]++;
            nxt[pre[a[i]]]=i;
            pre[a[i]]=i;
            if(vis[a[i]]>1)
                now^=a[i];
            b[i]=now;
            //debug(b[i]);
        }
        cin>>m;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&ql,&qr);
            Q[ql].push_back(MP(qr,i));
        }
        for(i=1;i<=n;i++)
        {
            //debug(sum);
            for(j=0;j<Q[i].size();j++)
                ans[Q[i][j].se]=Get(Q[i][j].fi)^b[Q[i][j].fi];
            ql=nxt[i];
            if(ql)
            {
                sum^=a[i];
                Add(ql,a[i]);
            }
        }
        for(i=1;i<=m;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
    

    总结

    期望得分:100 + 55 + 80 = 235

    实际得分:100 + 55 + 80 = 235

    暴力没挂真的感动。越来越菜了

    一言

    那时我怎么都想不到,原来也有这一天,念及你,竟既无风雨也无晴。 ——我亦飘零久

  • 相关阅读:
    tmp:算法数据结构
    [转]Open Live Writer 配置
    GCC ,Clang 与 make,cmake 一览
    概率统计(1):数据分布
    ISP基础(31):Lost Frame Strategy
    支付宝对接授权及加好友
    css实现定宽高比(非内容撑出)
    display:table实现多列等高布局
    vue挂载全局组件
    两个数组根据指定字段去重
  • 原文地址:https://www.cnblogs.com/wxyww/p/9923324.html
Copyright © 2011-2022 走看看