COGS:1822. [AHOI2013]作业

1822. [AHOI 2013] 作业

★★★   输入文件:ahoi2013_homework.in   输出文件:ahoi2013_homework.out   简单对比
时间限制:20 s   内存限制:512 MB

【题目描述】

【输入格式】

【输出格式】

【样例输入】

3 4

1 2 2

1 2 1 3

1 2 1 1

1 3 1 3

2 3 2 3

【样例输出】

2 2

1 1

3 2

2 1

【提示】

N=100000,M=1000000

数据极弱(和BZOJ相比),请放心A

【来源】

BZOJ 3236

 

分析

莫队,用树状数组来维护求值,一个求出现不同数的个数,另一个满足的数字个数。复杂度$O(n\sqrt n log_2n)$

另一种做法:由于这些数都是小于等于n的,所以对权值进行分块,修改$O(1)$,查询$O(\sqrt n)$,总复杂度$O(m \sqrt n)$

交了几次,最后一个点老是TLE,然后想尽办法,读入优化,inline内联函数,最后写上了输出优化。。。还是TLE,之后才发现ans数组开小了,直接开了MAXN,QAQ

代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cmath>
  4 using namespace std;
  5  
  6 const int MAXN = 100100;
  7 struct Que{
  8     int l,r,a,b,block,id;
  9     bool operator < (const Que &a) const 
 10     {
 11         if (block==a.block) return r < a.r;
 12         return block < a.block;
 13     }
 14 }q[1000100];
 15 int a[MAXN],cnt[MAXN],tr[2][MAXN],pr[15];
 16 int ans1[1000100],ans2[1000100];
 17 int n,m,pos,len;
 18 
 19 inline int read()
 20 {
 21     int x=0,f=1;char ch=getchar();
 22     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 23     while(ch>='0'&& ch<='9'){x=x*10+ch-'0';ch=getchar();}
 24     return x*f;
 25 }
 26 inline int lowbit(int x)
 27 {
 28     return x & (-x);
 29 }
 30 inline void change(int x,int c,int t)
 31 {
 32     while (x<=n)
 33     {
 34         tr[t][x] += c;
 35         x += lowbit(x);
 36     }
 37 }
 38 inline int query(int x,int t)
 39 {
 40     int res = 0;
 41     while (x)
 42     {
 43         res += tr[t][x];
 44         x -= lowbit(x);
 45     }
 46     return res;
 47 }
 48 inline void update(int x,int c)
 49 {
 50     if (cnt[x]==0) change(x,1,1);
 51     cnt[x] += c;
 52     if (cnt[x]==0) change(x,-1,1);
 53     change(x,c,0);
 54 }
 55 inline void solve()
 56 {
 57     int l = 1, r = 0;
 58     for (int i=1; i<=m; ++i)
 59     {
 60         for (; l>q[i].l; ) update(a[--l], 1);
 61         for (; r<q[i].r; ) update(a[++r], 1);
 62         for (; l<q[i].l; ) update(a[l++], -1);
 63         for (; r>q[i].r; ) update(a[r--], -1);
 64         ans1[q[i].id] = query(q[i].b, 0) - query(q[i].a-1, 0);
 65         ans2[q[i].id] = query(q[i].b, 1) - query(q[i].a-1, 1);
 66     }
 67 }
 68 inline void print(int x) 
 69 {
 70     while (x)
 71         pr[++len] = x%10, x/=10;
 72     if (!len) putchar('0');
 73     while (len)
 74         putchar(pr[len--]+'0');
 75 }
 76 int main()
 77 {
 78     freopen("ahoi2013_homework.in","r",stdin);
 79     freopen("ahoi2013_homework.out","w",stdout);
 80     n = read(); m = read();
 81     pos = (int)sqrt(n);
 82     for (int i=1; i<=n; ++i)
 83         a[i] = read();
 84     for (int i=1; i<=m; ++i)
 85     {
 86         q[i].l = read(); q[i].r = read();
 87         q[i].a = read(); q[i].b = read();
 88         q[i].block = (q[i].l-1)/pos+1;
 89         q[i].id = i;
 90     }
 91     sort(q+1,q+m+1);
 92     solve();
 93     for (int i=1; i<=m; ++i)
 94     {
 95         print(ans1[i]),putchar(' ');
 96         print(ans2[i]),putchar('\n');
 97         //printf("%d %d\n",ans1[i],ans2[i]);
 98     }
 99     return 0;
100 }

 备注:luogu提交地址

posted @ 2017-07-11 15:25  MJT12044  阅读(263)  评论(0编辑  收藏  举报