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\n", 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\n",ans);
   }
}

  

 

 

posted on 2020-02-03 16:55  师姐的迷弟  阅读(165)  评论(0编辑  收藏  举报

导航