zoukankan      html  css  js  c++  java
  • codeforces 1257

    https://www.luogu.com.cn/problem/CF1257F

    简单来说就是:给你 n 个数 a[ 1 ]  ~ a[ n ], n <= 100; 让你找一个 x ,使得每个元素异或x后的每个新元素上的二进位上的1的个数一样。

    思路:每个元素最多30个位置,可以想到的就是我们枚举这个x,因为元素个数也就100个;

    所以最简单粗暴的方法就是枚举出这个x然后与每个元素进行异或,将异或结果保存下来,全都一样就是解了;

    但是我们知道对于这种暴力枚举,我们都可以想到一些小优化,折半枚举。所以我们将x的30个位置拆成两半,cnt【0】【1】,表示这个x异或第一个元素后,后15位置有1的个数,cnt【1】【1】,表示这个x异或第一个元素后,前15个位置有1的个数;

    所以我们需要求出来的就是cnt【0】【1】+cnt【1】【1】=cnt【0】【2】+cnt【1】【2】=.......;

    -(+cnt【1】【2】-cnt【1】【1】)=cnt【0】【2】-cnt【0】【1】

    所以就是我们先将所由左侧的求i出来后存进map,再让枚举右侧的时候查询map里面有没有记录过的,有就直接得出答案。

    #include <bits/stdc++.h>
    #define LL long long
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define INF 0x3f3f3f3f
    #define inf 0x3f3f3f3f3f3f3f3f
    #define mem(i, j) memset(i, j, sizeof(i))
    #define pb push_back
    using namespace std;
    int ans = -1, n;
    map < vector< int >, int > mp;
    vector< int > Q;
    int a[105];
    void dfs1(int num, int statu){
        if(num > 15) {
            Q.clear();
            for(int i = 1; i <= n; i++) {
                Q.push_back(__builtin_popcount((statu ^ a[i]) % (1 << 15)));
            }
            for(int i = 1; i < n; i++) {
                Q[i - 1] = Q[i] - Q[i - 1];
            }
            Q.pop_back();
            if(!mp[Q]) mp[Q] = statu;
            return ;
        }
        dfs1(num + 1, statu);
        dfs1(num + 1, statu | (1 << (num - 1)));
    }
    void dfs2(int num, int statu) {
        if(num > 15) {
            Q.clear();
            for(int i = 1; i <= n; i++){
                ///__builtin_popcount(x) 用于计算x的二进制位上1的个数。
                Q.push_back(__builtin_popcount(statu ^ (a[i] >> 15)));
            }
            for(int i = 1; i < n; i++) {
                Q[i - 1] = -1 * (Q[i] - Q[i - 1]);
            }
            Q.pop_back(); /// 弹出最后一个元素。
            if(mp[Q]) {
                ans = mp[Q] | (statu << 15);
            }
            return ;
        }
        dfs2(num + 1, statu);
        dfs2(num + 1, statu | (1 << (num - 1)));
    }
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        dfs1(1, 0); dfs2(1, 0);
        printf("%d
    ", ans);
        return 0;
    }
    

    E

    https://www.luogu.com.cn/problemnew/solution/CF1257E

    例如

    1~i    cnt1[n]-cnt1[i]

    i+1~j cnt2[i]+cnt2[n]-cnt2[j];

    j+1~n  cnt3[j]

    #include <bits/stdc++.h>
    
    #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define ll long long
    #define LL long long
    using namespace std;
    const int maxn = (ll) 2e5 + 5;
    const int mod = 1000000007;
    const int inf = 0x3f3f3f3f;
    int cnt1[maxn], cnt2[maxn], cnt3[maxn];
    int minn[maxn];
    vector<int> v1, v2, v3;
    
    int main() {
        start;
        int k1, k2, k3;
        cin >> k1 >> k2 >> k3;
        v1.resize(k1 + 5);
        v2.resize(k2 + 5);
        v3.resize(k3 + 5);
        /*输入并标记*/
        for (int i = 1; i <= k1; ++i) {
            cin >> v1[i];
            ++cnt1[v1[i]];
        }
        for (int i = 1; i <= k2; ++i) {
            cin >> v2[i];
            ++cnt2[v2[i]];
        }
        for (int i = 1; i <= k3; ++i) {
            cin >> v3[i];
            ++cnt3[v3[i]];
        }
        int n = k1 + k2 + k3;
        for (int i = 1; i <= n; ++i) {//前缀和
            cnt1[i] = cnt1[i - 1] + cnt1[i];
            cnt2[i] = cnt2[i - 1] + cnt2[i];
            cnt3[i] = cnt3[i - 1] + cnt3[i];
        }
        /*如分析*/
        for (int i = 0; i <= n; ++i)
            minn[i] = cnt3[i] - cnt2[i];
        for (int i = n - 1; i >= 0; --i)
            minn[i] = min(minn[i + 1], minn[i]);
        int ans = inf;
        for (int i = 0; i <= n; ++i) {
            int t = cnt2[i] - cnt1[i] + minn[i] + cnt1[n] + cnt2[n];
            ans = min(ans, t);
        }
        cout << ans;
        return 0;
    }
    

      D

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    
    int n,m,a[maxn],suf[maxn],b[maxn],p[maxn],s[maxn];
    int main() {
       int t;scanf("%d",&t);
       while(t--) {
       	scanf("%d",&n);
       	for(int i=1;i<=n;i++) b[i]=-1;
       	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
       	scanf("%d",&m);
       	for(int i=1;i<=m;i++) scanf("%d %d",&p[i],&s[i]),b[s[i]]=max(b[s[i]],p[i]);
       	suf[n+1]=-1;
       	for(int i=n;i>=1;i--) suf[i]=max(suf[i+1],b[i]);
       	int pos=1,ans=0;
       	while(pos<=n) {
       		int cur=pos;
       		int maxx=a[pos];
       		while(cur<=n && suf[cur-pos+1]>=maxx) {
       			cur++;
       			maxx=max(maxx,a[cur]);
       		}
       		if(cur==pos) {ans=-1;break;}
       		ans++;
       		pos=cur;
    
       	}
       	printf("%d
    ",ans);
       }
    }
    

      

  • 相关阅读:
    假如时光倒流,我会这么学习Java
    一位资深程序员大牛给予Java初学者的学习路线建议
    Java基础部分全套教程.
    假如时光倒流,我会这么学习Java
    Window Location对象
    Window Screen对象
    Window
    easyui datagrid 清除缓存方法
    easyui tree扩展tree方法获取目标节点的一级子节点
    JavaScript 对象
  • 原文地址:https://www.cnblogs.com/hgangang/p/12256309.html
Copyright © 2011-2022 走看看