一个新奇的思路 & 求卡常
查看原帖
一个新奇的思路 & 求卡常
723238
wukaichen888楼主2023/7/17 12:59

数据好水!!!

模拟赛原题。

听到机房大佬 sbh 说 log2nlog^2n 不如 n\sqrt n,蒟蒻突发奇想,能不能用分块做到修改 O(n)O(\sqrt n) 询问 O(1)O(1) 卡过去呢?

然后在 O2 加持下卡了 90pts,提交记录

求卡过去捏

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
typedef long long ll;
const int N=2e6+5;
int n,m,op[N],X[N],Y[N],Z[N],l,r,mid;
int b[N],R,K,L,l2,pos[N];
struct BIT{
	ll c[N],c2[N];
	void add(int x,int y){
		for(register int i=x;pos[i]==pos[x];i++) c[i]+=y;
		for(register int i=pos[x];i<=L;i++) c2[i]+=y;
	}
	ll query(int x){return x<0?0:(pos[x]?c2[pos[x]-1]+c[x]:c[x]);}
}A,B;
inline ll val(int x){return min(A.query(x),B.query(R)-B.query(x-1));}
char *p1,*p2,buf[10000005];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,10000000,stdin),p1==p2)?EOF:*p1++)
int read(){
    int x=0,f=1;char ch=nc();
    while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
    while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();
   	return x*f;
}
int main(){
//	freopen("icefire.in","r",stdin);
//	freopen("icefire.out","w",stdout);
	m=read();
	for(register int i=1;i<=m;++i){
		op[i]=read();
		if(op[i]==1) X[i]=read(),Y[i]=read(),Z[i]=read(),b[++R]=Y[i];
		else X[i]=read();
	}
	sort(b+1,b+R+1);
	R=unique(b+1,b+R+1)-b-1;
	K=max((int)(sqrt(R)),1);
	for(register int i=0;i<=R;i++)
		L=max(L,pos[i]=i/K+1);
	for(register int i=1;i<=m;i++)
		if(op[i]==1)
			Y[i]=lower_bound(b+1,b+R+1,Y[i])-b;
	for(register int i=1;i<=m;i++){
		if(op[i]==1){
			if(!X[i]) A.add(Y[i],Z[i]);
			else B.add(Y[i],Z[i]);
		}
		else{
			if(!X[X[i]]) A.add(Y[X[i]],-Z[X[i]]);
			else B.add(Y[X[i]],-Z[X[i]]);
		}
		l=0,r=R;
		while(l<r){
			mid=l+r+1>>1;
			if(A.query(mid)<B.query(R)-B.query(mid-1)) l=mid;
			else r=mid-1;
		}
		if(!val(l)&&!val(l+1)) puts("Peace");
		else{
			while(val(l+1)>=val(l)) l++;
			printf("%d %lld\n",b[l],val(l)<<1);
		}
	}
	return 0;
}
2023/7/17 12:59
加载中...