版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/84894213
描述
有 这 个基因
一个基因
可以进化为序列中在它之后的基因
这个进化的复杂度,等于
的值
求进化后值小于 的方案数
思路
先扯淡
考试的时候就推出了
的优秀做法,真不知道写题解的人是怎么想的,竟然打线段树。。。开氧气后还比我快
正题
先把题解中的话引出来
说实话我考场都A了还没看懂题解,写的什么鬼
个人做法:
我们发现若
能合并到
那么显然
也能合并到
,根据这个特性,我们用一个队列维护一端可以被合并的值,入队和出对操作的判断要用位运算
时间复杂度:
暴力代码
#include<cstdio>
#include<cctype>
#include<algorithm>
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int n,a[100001],yh[5001][5001],m,ans;
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline int read()
{
char c;int d=1,f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(register long long x)
{
if(x<0)write(45),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
return;
}
signed main()
{
freopen("1.txt","r",stdin);
freopen("jhxl.txt","w",stdout);
n=read();m=read();
r(i,1,n) yh[i][i]=a[i]=read();
r(i,1,n-1) r(j,i+1,n) {yh[i][j]=yh[i][j-1]|a[j];if(yh[i][j]<m) ans++;}
write(ans);
}
正解
#include<cstdio>
#include<cctype>
#include<algorithm>
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#define r(i,a,b) for(register int i=a;i<=b;i++)
#define getk r(j,0,30) if(now[j]) k|=1<<j
using namespace std;int n,a[100001],m,head,now[32],k;
long long ans;
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline int read()
{
char c;int d=1,f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(register long long x)
{
if(x<0)write(45),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
return;
}
signed main()
{
freopen("1.txt","r",stdin);
freopen("jhxl2.txt","w",stdout);
n=read();m=read();
r(i,1,n) a[i]=read();
r(i,0,30) if((a[1]>>i)&1) now[i]++;
head=1;
r(i,2,n)
{
r(j,0,30) if((a[i]>>j)&1) now[j]++;//放入对尾
k=0;
getk;
while(k>=m&&head<i)//不满足要求剔除对头
{
r(j,0,30) if((a[head]>>j)&1) now[j]--;
k=0;
getk;
head++;
}
ans+=i-head;//加上方案
}
write(ans);
}
Rand生成
#include<cstdlib>
#include<cstdio>
#include<ctime>
using namespace std;
signed main()
{
freopen("1.txt","w",stdout);
srand(time(0));
printf("5000 %d\n",1+rand()%10000);
for(register int i=1;i<=5000;i++) printf("%d ",1+rand()%10000);
}
d(对)p(拍)
#include<cstdlib>
#include<cstdio>
#include<ctime>
using namespace std;double t1,t2,t3;
signed main()
{
for(register int i=1;i<1001;i++)
{
system("rand.exe");
t1=clock();
system("jhxl.exe");
t2=clock();
system("jhxl2.exe");
t3=clock();
if(system("fc jhxl.txt jhxl2.txt"))
{printf("测试点:#%3d 测试点信息:WA",i);return 0;}
else printf("测试点:#%3d 测试点信息:AC n方用时:%0.3lfms nlogn用时:%0.3lfms\n",i,t2-t1,t3-t2);
}
}