题目链接:https://ac.nowcoder.com/acm/contest/5556/E
输入
5
1 2
2 3
3 4
4 5
5 6
输出
26
备注:
先试一个样例
2
1 2
1 2
3
把其中的bitset输出
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<bitset>
#include<limits.h>
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r>>1)
#define over(i,s,t) for(register int i=s;i<=t;++i)
#define lver(i,t,s) for(register int i=t;i>=s;--i)
//#define int __int128
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
const int N=1e6+7;
const int mod=1e9+7;
const ll INF=1e15+7;
const double EPS=1e-10;//趋近为0
int n;
int l,r;
bitset<10>a,b;
int main()
{
cin>>n;
b[0]=1;
over(i,1,n){
scanf("%d%d",&l,&r);
cout<<"b:"<<" ";
for (int i=0;i<10;++i) {
cout<<b[i];
}
puts("");
over(j,l,r){
a|=b<<(j*j);
cout<<"a:"<<" ";
for (int i=0;i<10;++i) {
cout<<a[i];
}
puts("");
}
b=a;
a.reset();
}
cout<<"b:"<<" ";
for (int i=0;i<10;++i) {
cout<<b[i];
}
puts("");
printf("%d\n",b.count());
return 0;
}
注意这里是从高位到低位倒序输出
解释一下这里的样例。
首先初始化必须b[0]=1
即第1位 - > 0,当前的和为0
第一次输入1,2.
全部加上,就是a|=b<<1
。
a的第二位变为1,a=010000,即第2位 - > 1当前的和有1
然后是
b<<4=10000,a|b=000010010
。代表着有2和4两种情况。
然后是1,全体左移1,就是全体的数加上1。
然后2,全体左移4,即是全体数加4。
因为是|
,按位或运算,所以不会出现重复计算的情况,直接用b.count()
得到有多少个1既是有多少种情况。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<bitset>
#include<limits.h>
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r>>1)
#define over(i,s,t) for(register int i=s;i<=t;++i)
#define lver(i,t,s) for(register int i=t;i>=s;--i)
//#define int __int128
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
const int N=1e6+7;
const int mod=1e9+7;
const ll INF=1e15+7;
const double EPS=1e-10;//趋近为0
int n;
int l,r;
bitset<N>a,b;
int main()
{
cin>>n;
b[0]=1;
over(i,1,n){
scanf("%d%d",&l,&r);
over(j,l,r){
a|=b<<(j*j);
}
b=a;
a.reset();
}
printf("%d\n",b.count());
return 0;
}