BZOJ2527: [Poi2011]Meteors

这个。。。一开始用的是longlong 然后改成int就wa了。。。。

时间垫底。。。。。

可怕


全局分治  然后用线段树维护的时候直接永久化标记  不用下传


然后这一题和上一道树套树一样,又是因为自己傻逼少了一倍的线段树节点然后一直OLE不知道怎么了。。。

人傻没办法

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdlib>
using namespace std;
char c;
inline void read(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')
	a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Segement
{
   int l,r,flag;
}Tree[2000001];
void Segement_Build(int place,int l,int r)
{
	Tree[place].l=l;Tree[place].r=r;
	if(l^r)
	  Segement_Build(place<<1,l,(l+r)>>1),Segement_Build(place<<1|1,((l+r)>>1)+1,r);
}
int  Segement_data(int place,int l)
{
	if(Tree[place].l==Tree[place].r)
	    return Tree[place].flag;
	if(Tree[place<<1].r>=l)
	   return Segement_data(place<<1,l)+Tree[place].flag;
	return Segement_data(place<<1|1,l)+Tree[place].flag;
}
int n,m;
void Segement_ADD(int place,int l,int r,int delta)
{
	if(Tree[place].l>=l&&Tree[place].r<=r)
	   {Tree[place].flag+=delta;return;}
	if(Tree[place<<1].r>=l)
	  Segement_ADD(place<<1,l,r,delta);
	if(Tree[place<<1|1].l<=r) 
	  Segement_ADD(place<<1|1,l,r,delta);
}
struct Opt
{
	int x,y,z;
}Line[400001];
inline void add(int a,int b,int d){	if(a>b)Segement_ADD(1,a,m,d),Segement_ADD(1,1,b,d);	else Segement_ADD(1,a,b,d);}
inline void Plus(int x,int k){add(Line[x].x,Line[x].y,Line[x].z*k);}
vector<int>Country[400001];
int T=0;
int ID[400001];
int need[400001];
int ans[400001];
bool Mark[400001];
int tp[400001];
void Solve(int IDl,int IDr,int ansl,int ansr)
{
     if(IDl>IDr)return;
	 if(ansl>ansr)return;
	 if(ansl==ansr)	
	    {
		   for(int i=IDl;i<=IDr;i++)
		     ans[ID[i]]=ansl;
		   return;
		}
	int ansM=(ansl+ansr)>>1;
	while(T<=ansM)T++,Plus(T,1);
	while(T>ansM)Plus(T,-1),T--;
    int i,j,k,cnt=0;
    int  now;
    for(i=IDl;i<=IDr;i++)
       {
       	 now=0;
       	 for(j=0;j<Country[ID[i]].size()&&now<need[ID[i]];j++)
       	    now+=Segement_data(1,Country[ID[i]][j]);
	     if(now>=need[ID[i]])
	        Mark[i-IDl+1]=true,cnt++;
	     else Mark[i-IDl+1]=false;
	   }
	j=0,k=0;
	for(i=IDl;i<=IDr;i++)
      if(Mark[i-IDl+1])
         tp[++j]=ID[i];
        else tp[++k+cnt]=ID[i];
    for(i=IDl;i<=IDr;i++)
       ID[i]=tp[i-IDl+1];
      Solve(IDl,IDl+cnt-1,ansl,ansM),Solve(IDl+cnt,IDr,ansM+1,ansr);    
}

int q;
int pr[400001];
int main()
{
	int i,j;
	read(n),read(m);
	Segement_Build(1,1,m);
	Line[0].x=1;
	Line[0].y=m;
	Line[0].z=0;
	for(i=1;i<=m;i++)
	  read(j),Country[j].push_back(i);
	for(i=1;i<=n;i++)
	  ID[i]=i,read(need[i]);
	read(q);
	for(i=1;i<=q;i++)
	   read(Line[i].x),read(Line[i].y),read(Line[i].z);
   Line[++q]=(Opt){1,m,1e9};
   Solve(1,n,1,q);
   for(i=1;i<=n;i++)
     pr[ID[i]]=ans[ID[i]];
    for(i=1;i<=n;i++)
     if(pr[i]!=q)
	 printf("%lld\n",pr[i]);
     else puts("NIE");
	return 0;
}


你可能感兴趣的:(bzoj)