题目背景
这是一道模版题
可以使用bitset,CDQ分治,K-DTree等方式解决。
题目描述
有 个元素,第 个元素有 、、 三个属性,设 表示满足 且 且 的 的数量。
对于 ,求 的数量
输入输出格式
输入格式:
第一行两个整数 、,分别表示元素数量和最大属性值。
之后 行,每行三个整数 、、,分别表示三个属性值。
输出格式:
输出 行,第 行表示 的 的数量。
输入输出样例
输入样例#1:
10 3 3 3 3 2 3 3 2 3 1 3 1 1 3 1 2 1 3 1 1 1 2 1 2 2 1 3 2 1 2 1
输出样例#1:
3 1 3 0 1 0 1 0 0 1
说明
洛谷评测机刷了一上午屏终于搞定了!
这道题因为会有重复点存在,所以cdq分治离线时一定要把重复的点缩为一个。
然后树状数组不要清零memset……
另外,别对拍完不删freopen
#include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) x&-x using namespace std; const int maxn=1e5+100; const int maxk=2e5+100; int n,k; int ans[maxn]; int id[maxn]; int sum[maxn]; struct point{ int x,y,z,n,id,sum; }rp[maxn],p[maxn]; bool cmp_xyz(const point &a,const point &b){ return a.x==b.x?(a.y==b.y?a.z<b.z:a.y<b.y):a.x<b.x; } bool cmp_yzx(const point &a,const point &b){ return a.y==b.y?(a.z==b.z?a.x<b.x:a.z<b.z):a.y<b.y; } namespace BIT{ int tree[maxk]; void add(int x,int w){while(x<=k) tree[x]+=w,x+=lowbit(x);} int query(int x){int ret=0;while(x) ret+=tree[x],x-=lowbit(x);return ret;} } void cdq(int l,int r){ if(l==r) return ; int mid=(l+r)/2; cdq(l,mid); cdq(mid+1,r); sort(p+l,p+r+1,cmp_yzx); for(int i=l;i<=r;i++){ if(p[i].id<=mid) BIT::add(p[i].z,p[i].sum); else ans[p[i].n] += BIT::query(p[i].z); } for(int i=l;i<=r;i++) if(p[i].id<=mid) BIT::add(p[i].z,-p[i].sum); } int main(){ freopen("s.in", "r", stdin); freopen("s.out", "w", stdout); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d%d%d",&rp[i].x,&rp[i].y,&rp[i].z); rp[i].n=i; } sort(rp+1,rp+n+1,cmp_xyz); int cnt=1; p[1]=rp[1];p[1].id=1;p[1].sum=1; for(int i=2;i<=n;i++){ if(rp[i].x==rp[i-1].x && rp[i].y==rp[i-1].y && rp[i].z==rp[i-1].z) p[cnt].sum++; else{ p[++cnt]=rp[i]; p[cnt].id=cnt; p[cnt].sum=1; } } cdq(1,cnt); for(int i=1;i<=cnt;i++) id[p[i].n]=i; for(int i=1;i<=n;i++) sum[ans[i]+p[id[i]].sum-1]+=p[id[i]].sum; for(int i=0;i<=n-1;i++) printf("%d\n",sum[i]); return 0; }
++---++---+2018/1/24+---++---++
更新了一版CDQ,发现以前常数大代码丑。这次在洛谷372ms:
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; const int maxn = 1e5 + 5; struct point { int x, y, z, pos, id, cnt; }rp[maxn], p[maxn], mg[maxn]; int n, k, a, b, c, ans[maxn], sum[maxn], cnt; int mcnt, pl, pr; inline char gc(){ static char buf[5000000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 5000000, stdin), p1 == p2) ? EOF : *p1++; } inline void read(int & x) { x = 0;static char c = gc(); while(!isdigit(c)) c = gc(); while(isdigit(c)) x = x * 10 + c - '0', c = gc(); } void write(int x) { if(x / 10) write(x / 10); putchar(x % 10 + '0'); } bool cmp_xyz(const point &a, const point &b) { return a.x == b.x ? (a.y == b.y ? (a.z < b.z) : a.y < b.y) : a.x < b.x; } inline bool cmp_yzx(const point &a, const point &b) { return a.y == b.y ? (a.z == b.z ? (a.x < b.x) : a.z < b.z) : a.y < b.y; } namespace BIT { int tree[maxn << 1]; #define lowbit(x) ((x) & (-(x))) void add(int x, int p) {while(x <= k) tree[x] += p, x += lowbit(x);} int query(int x) { int ans = 0; while(x) ans += tree[x], x -= lowbit(x); return ans; } } void cdq(int l, int r) { if(l == r) return; int mid = l + r >> 1; cdq(l, mid), cdq(mid + 1, r); mcnt = 0, pl = l, pr = mid + 1; while(pl <= mid && pr <= r) if(cmp_yzx(p[pl], p[pr])) mg[++mcnt] = p[pl++]; else mg[++mcnt] = p[pr++]; while(pl <= mid) mg[++mcnt] = p[pl++]; while(pr <= r) mg[++mcnt] = p[pr++]; for(register int i = 1; i <= mcnt; ++i) p[l + i - 1] = mg[i]; for(register int i = l; i <= r; ++i) { if(p[i].id <= mid) BIT::add(p[i].z, p[i].cnt); else ans[p[i].pos] += BIT::query(p[i].z); } for(register int i = l; i <= r; ++i) if(p[i].id <= mid) BIT::add(p[i].z, -p[i].cnt); } int main() { read(n), read(k); for(register int i = 1; i <= n; ++i) { read(a), read(b), read(c); rp[i] = (point) {a, b, c, i, 0, 1}; } sort(rp + 1, rp + n + 1, cmp_xyz); for(register int i = 1; i <= n; ++i) { if(rp[i].x == rp[i - 1].x && rp[i].y == rp[i - 1].y && rp[i].z == rp[i - 1].z) ++p[cnt].cnt; else p[++cnt] = rp[i], p[cnt].id = cnt; } cdq(1, cnt); for(register int i = 1; i <= cnt; ++i) sum[ans[p[i].pos] + p[i].cnt - 1] += p[i].cnt; for(register int i = 0; i < n; ++i) write(sum[i]), putchar('\n'); return 0; }
没有帐号? 立即注册