一.省赛训练补题
(1) training round 4
Problem H. Binary Craziness
题面
训练时不知道怎么优化,10^6至少优化到nlogn 。
从第一个样例分析:
每个点的d[u]为:2 2 2 3 2 1
思想进程:
1.刚开始先把暴力的做法写好 再从暴力的地方看看有没有哪能优化
2. 把两重循环写下来会发现
2 2 2 3 2 1
2 2 2 3 2 1
上面的每个数都要和其他的数 做一次 f ()运算
3和2做四次f ()运算 3和1做1次f()运算
而 每个数和自己本身做f()运算 结果为 0 所以不用考虑
所以 现在我们 要记录 每个数字出现的次数 go!
3.用d[i] 记录每个点的有关边数 map<LL,LL>mp 记录 次数 因为mp没办法做相关的循环运算
所以放到 vector里进行
(注意取long long)
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const int N=1e6+5,mod=998244353;
int a[N];
int n,m;
map<LL,LL>mp;
LL f(LL x,LL y)
{
return (x^y)*(x|y)*(x&y);
}
vector<PII>v;
int main()
{
scanf("%d%d",&n,&m);
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
a[u]++;
a[v]++;
}
for(int i=1;i<=n;i++)
{
mp[a[i]]++;
}
for(auto t:mp)
{
v.push_back({t.first,t.second});
}
LL sum=0;
for(int i=0;i<v.size();i++)
for(int j=i+1;j<v.size();j++)
{
LL x1=v[i].first,sum1=v[i].second;
LL x2=v[j].first,sum2=v[j].second;
LL k=f(x1,x2);
sum=(sum+k*sum1%mod*sum2%mod)%mod;
}
printf("%lld",sum);
return 0;
}
总结:一道优化循环的题目