逆天出题人卡常
查看原帖
逆天出题人卡常
575698
262620zzj楼主2024/11/4 20:16

真的优化不动了啊,递归全都改成循环了,快读快些、写也用了。求助

#include<bits/stdc++.h>
using namespace std;
//#define LOCAL
#include<iostream>
#include<cstdio>
#include<climits>
#include<cctype>

using namespace std;
namespace ly
{
    namespace IO
    {
        #ifndef LOCAL
            constexpr auto maxn=1<<20;
            char in[maxn],out[maxn],*p1=in,*p2=in,*p3=out;
            #define getchar() (p1==p2&&(p2=(p1=in)+fread(in,1,maxn,stdin),p1==p2)?EOF:*p1++)
            #define flush() (fwrite(out,1,p3-out,stdout))
            #define putchar(x) (p3==out+maxn&&(flush(),p3=out),*p3++=(x))
            class Flush{public:~Flush(){flush();}}_;
        #endif
        namespace usr
        {
            template<typename type>
            inline type read(type &x)
            {
                x=0;bool flag(0);char ch=getchar();
                while(!isdigit(ch)) flag^=ch=='-',ch=getchar();
                while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
                return flag?x=-x:x;
            }
            template<typename type>
            inline void write(type x)
            {
                x<0?x=-x,putchar('-'):0;
                static short Stack[50],top(0);
                do Stack[++top]=x%10,x/=10;while(x);
                while(top) putchar(Stack[top--]|48);
            }
            inline char read(char &x){do x=getchar();while(isspace(x));return x;}
            inline char write(const char &x){return putchar(x);}
            inline void read(char *x){static char ch;read(ch);do *(x++)=ch;while(!isspace(ch=getchar())&&~ch);}
            template<typename type>inline void write(type *x){while(*x)putchar(*(x++));}
            inline void read(string &x){static char ch;read(ch),x.clear();do x+=ch;while(!isspace(ch=getchar())&&~ch);}
            inline void write(const string &x){for(int i=0,len=x.length();i<len;++i)putchar(x[i]);}
            template<typename type,typename...T>inline void read(type &x,T&...y){read(x),read(y...);}
            template<typename type,typename...T>
            inline void write(const type &x,const T&...y){write(x),putchar(' '),write(y...),sizeof...(y)^1?0:putchar('\n');}
            template<typename type>
            inline void put(const type &x,bool flag=1){write(x),flag?putchar('\n'):putchar(' ');}
        }
        #ifndef LOCAL
            #undef getchar
            #undef flush
            #undef putchar
        #endif
    }using namespace IO::usr;
}using namespace ly::IO::usr;
const int N=264289;
typedef long long ll;
int n,m,_a[N],a[N],c[N],k,num,tot,x[4],f[N],g[N],r[N],root,self[N];
bool d[N];
ll s[N];
vector<int> vec[50];
inline void init(int u,int t){
	vec[t].push_back(u);
	if(u<<1<=tot)init(u<<1,t),init(u<<1|1,t);
}
inline void solve(int dep){
	root=1<<k-dep;
	num=1<<dep;
	self[root]=0;
	for(int i,j=0;j<vec[dep].size();j++){
		i=vec[dep][j];
		f[i]=-1;
		g[i]=num+1;
		if(i<<1<=tot){
			self[i<<1]=self[i<<1|1]=self[i];
			self[(i<<1)+d[i]]=max(self[(i<<1)+d[i]],r[i]);
		}
	}
	int begin=dep?(1<<dep-1)+1:1;
	for(int i=1;i<=min(num,n);i++){
		int id=i+(1<<k)-1;
		f[id]=a[i];
		int t=max(i,begin);
		while(1){
			id>>=1;
			if(id<root)break;
			int son=id*2+d[id];
			if(~f[son]){
				if(f[son]>=r[id])g[son^1]=min(g[son^1],t);
				else g[son]=min(g[son],t);
			}
			if(f[id]!=-1)break;
			if(f[son]>=r[id]||f[son]==-1)f[id]=f[son];
			else f[id]=f[son^1];
			if(f[id]==-1)break;
		}
	}
	for(int i,j=1;j<vec[dep].size();j++){
		i=vec[dep][j];
		g[i]=min(g[i],g[i>>1]);
	}
	for(int i=1;i<=num;i++){
		int id=i+(1<<k)-1;
		if(i<=n&&a[i]<self[id])g[id]=min(g[id],max(i,begin));
		s[begin]+=i;
		s[g[id]]-=i;
	}
}
inline void GOWORK(){
	read(x[0],x[1],x[2],x[3]);
	for(int i=1;i<=n;i++)a[i]=_a[i]^x[i%4];
	memset(s,0,sizeof(s));
	for(int d=0;d<=k;d++)solve(d);
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	ll ans=0;
	for(int i=1;i<=m;i++)ans^=i*s[c[i]];
	put(ans,1);
}
int main(){
//	freopen("arena5.in","r",stdin);
//	freopen("arena.out","w",stdout);
    read(n,m);
	for(int i=1;i<=n;i++)read(_a[i]);
	for(int i=1;i<=m;i++)read(c[i]);
	k=0;
    while(1<<k<n)k++;
    tot=(1<<k+1)-1;
    for(int i=1;i<=k;i++){
        for(int j=0;j<1<<k-i;j++){
        	char z;read(z);
//        	write(z,'|',j);
        	d[j+(1<<k-i)]=z-'0';
        	r[j+(1<<k-i)]=i;
		}
	}
//	for(int i=1;i<=15;i++)put(d[i],0);
	for(int i=0;i<=k;i++){
		init(1<<k-i,i);
		sort(vec[i].begin(),vec[i].end());
//		for(int j:vec[i])cout<<j<<' ';cout<<endl;
	}
    int DAY;read(DAY);
    while(DAY--)GOWORK();
    return 0;
}
2024/11/4 20:16
加载中...