VIJOS1976 - [NOIP2015]求和

2016/10/23

链表小小跑一下离散化,再用位运算判一下合法性。 最近做题越来越水了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100000 + 500;
#ifndef LCYTEST
#   define release(_x) { _x }
#   define debug(_x) ;
#else
#   define release(_x) ;
#   define debug(_x) { _x }
#endif
#define mod(x) (ULL(x) % 10007)
int num[MAX_N]; int N, M;
typedef unsigned long long ULL;
struct link {
    int n; link* next;
} POOL[MAX_N]; int ppos;
link* Head[MAX_N];

void addLink(int h, int n) {
    debug({ cout << h << "# " << n << endl; });
    POOL[ppos].n = n; POOL[ppos].next = Head[h];
    Head[h] = &POOL[ppos++];
}

int main() {
    release({ ios::sync_with_stdio(false); cin.tie(NULL); }); 
    cin >> N >> M;
    for(int i=1;i<=N;i++) {
        cin >> num[i];
    }

    int co;
    for(int i=1;i<=N;i++) {
        cin >> co;
        addLink(co, i);
    }

    ULL ans = 0;
    for(int i=1;i<=M;i++) {
        typedef link* It;
        for(It j=Head[i];j&&j->next;j=j->next) {
            debug({ cout << i << " " << j->n << endl; });
            for(It k=j->next;k;k=k->next) {
                if(((j->n)&1) == ((k->n)&1)) {
                    debug({ cout << i << " "<< j->n << " " << k->n << endl; });
                    ans = mod(ans + mod(j->n + k->n) * mod(num[j->n] + num[k->n]));
                }
            }
        }
    }

    cout << mod(ans) << endl;
}