比赛 国庆欢乐赛2 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 魔法卡片 最终得分 100
用户昵称 梦那边的美好ET 运行时间 7.535 s
代码语言 C++ 内存使用 23.81 MiB
提交时间 2025-10-04 12:01:10
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
// #define LOCAL
#define ll long long
#define db double
#define Ciallo true
#define pir pair <ll,ll>
#define fs first
#define sc second
#define MAXN 1000010
inline ll read(){
    ll f = 1, num = 0;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c=='-') f = -1;c = getchar();
    }
    while(c>='0'&&c<='9') num = num * 10 + c - '0', c = getchar();
    return num * f;
}

int n,m,q;
map <int, ll> mp[30];
ll ans[MAXN][30];
bool ins[MAXN];
int nxt[MAXN];
ll sum = 0;
queue <int> qu[30];
ll tot[30][MAXN];
// map <int, bool> vec[MAXN];

int main(int argc, char* argv[]){
    freopen("magic.in", "r", stdin);
    freopen("magic.out", "w", stdout);
    #ifdef FS
        freopen(argv[1], "r", stdin);
        freopen(argv[2], "w", stdout);
    #elif defined(LOCAL)
        freopen("w.in", "r", stdin);
        freopen("w.out", "w", stdout);
    #endif

    vector <vector <bool> > vec;
    n = read(),m = read(), q = read();
    vec.resize(n + 10);
    for(int i = 1;i <= m; ++i)sum += i * i;
    for(int i = 1;i <= n; ++i){
        vec[i].resize(m + 10);
        int x = read();
        for(int j = 1;j <= x; ++j){
            int p = read();
            vec[i][p] = Ciallo;
        }
        // cerr << i << endl;

        for(int j = 1;j <= min(i, 20); ++j){
            mp[j].clear();
        }
        // cerr << i << endl;

        for(int j = 1;j <= m; ++j){
            int S = 0;
            for(int u = 1;u <= min(i, 20); ++u){
                if(!vec[i - u + 1][j]){
                    S |= 1 << u - 1;
                }                
                if(!tot[u][S])qu[u].push(S);
                tot[u][S] += j * j;
            }
        }
        // cerr << i << endl;

        for(int j = 1;j <= min(i, 20); ++j){
            ll mn = 1e18;
            if(qu[j].size() < (1 << j) && !nxt[i]){
                nxt[i] = i - j + 1;
            }
            while(!qu[j].empty()){
                int now = qu[j].front();
                qu[j].pop();
                mn = min(mn, tot[j][now]);
                tot[j][now] = 0;
            }
            ans[i][j] = sum - mn;
        }
        // cerr << i << endl;
    }

    cerr << "done init\n";

    for(int i = 1;i <= q; ++i){
        int ql = read(),qr = read();
        if(qr - ql + 1 >= 20)printf("%lld\n", sum);
        else{
            if(ql <= nxt[qr])printf("%lld\n", sum);
            else printf("%lld\n", ans[qr][qr - ql + 1]);
        }
    }

    cerr << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << "s \n";
    return 0;
}