如下是我的 CDQ 代码:
int n,k;
struct Node
{
int a,b,c,cnt,ans;
}a[100005];
bool cmp1(const Node &a, const Node &b)
{
return a.a<b.a || a.a==b.a && a.b<b.b || a.a==b.a && a.b==b.b && a.c<b.c;
}
bool cmp2(const Node &a, const Node &b)
{
return a.b<b.b || a.b==b.b && a.c<b.c;
}
Node b[100005];
int tot=1;
int BIT[200005],final[200005];
#define lowbit(x) (x&(-x))
il void add(int pos, int val)
{
while(pos<=k) BIT[pos]+=val,pos+=lowbit(pos);
}
il int qry(int pos)
{
int __ans=0;while(pos) __ans+=BIT[pos],pos-=lowbit(pos);return __ans;
}
在 CDQ 的 solve 函数中,我们需要一个变量来存放结果。
当我这样写的时候,获得了 WA 10pts 的成绩:
// ans 数组用于记录答案,final 数组用于输出最终答案
int ans[200001];
void solve(int l, int r)
{
if(l>=r) return;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
sort(b+l,b+mid+1,cmp2);sort(b+mid+1,b+r+1,cmp2);
// cerr<<l<<' '<<r<<endl;
int i=mid+1,j=l;
while(i<=r)
{
// cerr<<">"<<i<<' '<<j<<endl;
while(j<=mid && b[j].b<=b[i].b)
{
add(b[j].c,b[j].cnt);
++j;
}
ans[i]+=qry(b[i].c);//注意这一行
i++;
}
For(k,l,j-1) add(b[k].c,-b[k].cnt);
}
int final[200005];
signed main()
{
read(n,k);
For(i,1,n) read(a[i].a,a[i].b,a[i].c);
sort(a+1,a+1+n,cmp1);
b[1]=a[1];b[1].cnt=1;
For(i,2,n)
{
if(a[i].a==a[i-1].a && a[i].b==a[i-1].b && a[i].c==a[i-1].c)
{
b[tot].cnt++;
}
else
{
b[++tot]=a[i];
b[tot].cnt=1;
}
} // 去重
solve(1,tot);
For(i,1,tot)
{
final[ans[i]+b[i].cnt-1]+=b[i].cnt; //注意这里
}
For(i,0,n-1) cout<<final[i]<<endl;
return 0;
}
但是这样写则可以 AC!
//用 Node 结构体中的元素 b[i].ans 记录答案,用 final 数组计算输出
void solve(int l, int r)
{
if(l==r) return;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
sort(b+l,b+mid+1,cmp2);sort(b+mid+1,b+r+1,cmp2);
// cerr<<l<<' '<<r<<endl;
int i=mid+1,j=l;
while(i<=r)
{
// cerr<<">"<<i<<' '<<j<<endl;
while(j<=mid && b[j].b<=b[i].b)
{
add(b[j].c,b[j].cnt);
++j;
}
b[i].ans+=qry(b[i].c);//注意这里
i++;
}
For(id,l,j-1) add(b[id].c,-b[id].cnt);
}
signed main()
{
read(n,k);
For(i,1,n) read(a[i].a,a[i].b,a[i].c);
sort(a+1,a+1+n,cmp1);
b[1]=a[1];b[1].cnt=1;
For(i,2,n)
{
if(a[i].a==a[i-1].a && a[i].b==a[i-1].b && a[i].c==a[i-1].c)
{
b[tot].cnt++;
}
else
{
b[++tot]=a[i];
b[tot].cnt=1;
}
}//去重
solve(1,tot);
For(i,1,tot)
{
final[b[i].ans+b[i].cnt-1]+=b[i].cnt;//注意这里
}
For(i,0,n-1) cout<<final[i]<<endl;
return 0;
}
按照我的个人理解,i 下标无论对应的是结构体元素还是一个新的数组,答案不是一样的吗(
求大佬赐教 qwq