bzoj 3781

又忘了给每个点标所属的块,瞬间就变成一个块了。

写莫队一定要试一下随机极限数据。

 1 /**************************************************************
 2     Problem: 3781
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:1184 ms
 7     Memory:2772 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12 #include <cmath>
13 #include <algorithm>
14 #define maxn 50010
15 using namespace std;
16  
17 typedef long long lng;
18  
19 int n, m, k;
20 int w[maxn];
21 int mccno[maxn], lx[maxn], rx[maxn], stot;
22 int cnt[maxn]; 
23 lng ans[maxn], cur_ans;
24  
25 struct Qu {
26     int l, r, id;
27     bool operator<( const Qu & b ) const {
28         return mccno[l]<mccno[b.l] || (mccno[l]==mccno[b.l] && r<b.r );
29     }
30 };
31 Qu qu[maxn];
32  
33 void init() {
34     memset( cnt, 0, sizeof(cnt) );
35     cur_ans = 0;
36 }
37 void add( int v ) {
38     cur_ans -= cnt[v]*cnt[v];
39     cnt[v]++;
40     cur_ans += cnt[v]*cnt[v];
41 }
42 void del( int v ) {
43     cur_ans -= cnt[v]*cnt[v];
44     cnt[v]--;
45     cur_ans += cnt[v]*cnt[v];
46 }
47  
48 void partition() {
49     int len = (int)sqrt(n)+1;
50     int stot = n/len;
51     rx[0] = 0;
52     for( int i=1; i<=stot; i++ ) {
53         lx[i] = rx[i-1]+1;
54         rx[i] = rx[i-1]+len;
55     }
56     if( rx[stot]!=n ) {
57         stot++;
58         rx[stot] = n;
59         lx[stot] = rx[stot-1]+1;
60     }
61     for( int i=1; i<=stot; i++ ) 
62         for( int j=lx[i]; j<=rx[i]; j++ )
63             mccno[j] = i;
64 }
65  
66 void work() {
67     sort( qu+1, qu+1+m );
68     for( int q=1,lf,rg; q<=m; q++ ) {
69         if( q==1 || mccno[qu[q].l]!=mccno[qu[q-1].l] ) {
70             lf = qu[q].l;
71             rg = lf-1;
72             init();
73         }
74         while( lf<qu[q].l ) del( w[lf++] );
75         while( lf>qu[q].l ) add( w[--lf] );
76         while( rg<qu[q].r ) add( w[++rg] );
77         while( rg>qu[q].r ) del( w[rg--] );
78         ans[qu[q].id] = cur_ans;
79     }
80 }
81  
82 int main() {
83     scanf( "%d%d%d", &n, &m, &k );
84     for( int i=1; i<=n; i++ )
85         scanf( "%d", w+i );
86     for( int i=1; i<=m; i++ ) {
87         scanf( "%d%d", &qu[i].l, &qu[i].r );
88         qu[i].id = i;
89     }
90     partition();
91     work();
92     for( int i=1; i<=m; i++ )
93         printf( "%lld
", ans[i] );
94 }
95  
96 
View Code
原文地址:https://www.cnblogs.com/idy002/p/4298123.html