전체 2점에서 CDQ로 나누기
전체 2점에서 CDQ로 나누기
1.전체2점
#include
#include
#include
#include
#include
#define mid ((nl+nr)>>1)
#define maxn 300005
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//
int n,m,k;
int res[maxn];
int id[maxn],temp[maxn];
int bel[maxn],ned[maxn];
int z[maxn],y[maxn],t[maxn];
vector<int>edge[maxn];
//
ll dat[maxn];
int lowbit(int now)
{
return (now&(-now));
}
void update(int now,int add)
{
for(int i=now;i<=m;i+=lowbit(i))
{
dat[i]+=add;
}
}
ll query(ll pos)
{
ll ans=0;
for(int i=pos;i>=1;i-=lowbit(i))
{
ans+=dat[i];
}
return ans;
}
void insert(int now,int op)
{
if(z[now]<=y[now])
{
update(z[now],op*t[now]);
update(y[now]+1,-op*t[now]);
}
else
{
update(z[now],op*t[now]);
update(1,op*t[now]);
update(y[now]+1,-op*t[now]);
}
}
ll sum[maxn];
//dfs( , )
void dfs(int ql,int qr,int nl,int nr)
{
if(ql>qr) return;
if(nl==nr)
{
for(int i=ql;i<=qr;i++)
{
res[id[i]]=nl;
}
return;
}
for(int i=nl;i<=mid;i++)
{
insert(i,1);
}
for(int i=ql;i<=qr;i++)// ql qr, , 。
{
sum[id[i]]=0;
}
for(int i=ql;i<=qr;i++)
{
int len1=edge[id[i]].size();
for(int j=0;j<len1;j++)
{
sum[id[i]]+=query(edge[id[i]][j]);
if(sum[id[i]]>=ned[id[i]]) break;
}
}
int cnt=0;
for(int i=ql;i<=qr;i++)// , ,
{
if(sum[id[i]]>=ned[id[i]])
cnt++;
}
int l1=ql,l2=ql+cnt;
for(int i=ql;i<=qr;i++)
{
if(sum[id[i]]>=ned[id[i]])
{
temp[l1++]=id[i];
}
else
{
temp[l2++]=id[i];
ned[id[i]]-=sum[id[i]];//
}
}
for(int i=ql;i<=qr;i++)
id[i]=temp[i];
for(int i=nl;i<=mid;i++)
{
insert(i,-1);//
}
dfs(ql,ql+cnt-1,nl,mid);
dfs(ql+cnt,qr,mid+1,nr);
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
int x;
x=read();
edge[x].push_back(i);
}
for(int i=1;i<=n;i++)
{
ned[i]=read();
id[i]=i;
}
k=read();
for(int i=1;i<=k;i++)
{
z[i]=read();
y[i]=read();
t[i]=read();
}
k++;
z[k]=1;y[k]=m;t[k]=1000000009;
dfs(1,n,1,k);
for(int i=1;i<=n;i++)
{
if(res[i]!=k) printf("%d
",res[i]);
else printf("NIE
");
}
}
2. CDQ 분할 치료
#include
#include
#include
#include
#define maxn 200005
#define mid ((l+r)>>1)
using namespace std;
struct nod
{
int x,y,z,id;
nod()
{
x=0;
y=0;
z=0;
id=0;
}
}a[maxn],b[maxn];
int n,k;
int dat[maxn];
int ans[maxn];
bool operator<(nod a,nod b)
{
return a.x!=b.x ? a.x<b.x : (a.y!=b.y ? a.y<b.y : a.z<b.z);
}
bool operator==(nod a,nod b)
{
return a.x==b.x && a.y==b.y && a.z==b.z;
}
int lowbit(int now)
{
return (now&(-now));
}
void add(int x,int val)
{
for(int i=x;i<=k;i+=lowbit(i))
dat[i]+=val;
}
int query(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=dat[i];
return ans;
}
void cdq(int l,int r)
{
if(l>=r) return;
cdq(l,mid);
cdq(mid+1,r);
int s1=l,s2=mid+1;
while(s1<=mid || s2<=r)
{
if(s2>r || (s1<=mid && a[s1].y<=a[s2].y))
{
add(a[s1].z,1);
b[l+(s1-l)+(s2-(mid+1))]=a[s1];
s1++;
}
else
{
ans[a[s2].id]+=query(a[s2].z);
b[l+(s1-l)+(s2-(mid+1))]=a[s2];
s2++;
}
}
for(int i=l;i<=mid;i++)
add(a[i].z,-1);
for(int i=l;i<=r;i++)
a[i]=b[i];
}
int cnt[maxn];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
a[i].id=i;
}
sort(a+1,a+1+n);
for(int i=n;i>=1;i--)
{
if(a[i]==a[i+1])
ans[a[i].id]=ans[a[i+1].id]+1;
// , , 。
}
cdq(1,n);
for(int i=1;i<=n;i++)
cnt[ans[i]]++;
for(int i=0;i<n;i++)
printf("%d
",cnt[i]);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.