QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#614265#9449. New School Termucup-team5071#TL 786ms19264kbC++209.7kb2024-10-05 16:02:472024-10-05 16:02:48

Judging History

你现在查看的是最新测评结果

  • [2024-10-05 16:02:48]
  • 评测
  • 测评结果:TL
  • 用时:786ms
  • 内存:19264kb
  • [2024-10-05 16:02:47]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5, P = 998244353;
typedef array<int,2> info;
int f[maxn];
info siz[maxn];
#define fp(i, a, b) for (int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define fd(i, a, b) for (int i = (a), i##_ = (b) - 1; i > i##_; --i)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
using arr = int[maxn];
using ll = int64_t;
/*---------------------------------------------------------------------------*/
class Cipolla {
    int P, I2{};
    using pll = pair<ll, ll>;
#define X first
#define Y second
    ll mul(ll a, ll b) const { return a * b % P; }
    pll mul(pll a, pll b) const { return {(a.X * b.X + I2 * a.Y % P * b.Y) % P, (a.X * b.Y + a.Y * b.X) % P}; }
    template<class T> T POW(T a, int b, T x) { for (; b; b >>= 1, a = mul(a, a)) if (b & 1) x = mul(x, a); return x; }
public:
    Cipolla(int p = 0) : P(p) {}
    pair<int, int> sqrt(int n) {
        int a = rand(), x;
        if (!(n %= P))return {0, 0};
        if (POW(n, (P - 1) >> 1, (int)1) == P - 1) return {-1, -1};
        while (POW(I2 = ((ll) a * a - n + P) % P, (P - 1) >> 1, (int)1) == 1) a = rand();
        x = (int) POW(pll{a, 1}, (P + 1) >> 1, {1, 0}).X;
        if (2 * x > P) x = P - x;
        return {x, P - x};
    }
#undef X
#undef Y
};
/*---------------------------------------------------------------------------*/
#define ADD(a, b) (((a) += (b)) >= P ? (a) -=P : 0) // (a += b) %= P
#define SUB(a, b) (((a) -= (b)) < 0 ? (a) += P: 0)  // ((a -= b) += P) %= P
#define MUL(a, b) ((ll) (a) * (b) % P)
//vector<int> getInv(int L) {
//    vector<int> inv(L); inv[1] = 1;
//    fp(i, 1, L - 1) inv[i] = MUL((P - P / i), inv[P % i]);
//    return inv;
//}
//auto inv = getInv(maxn); // NOLINT
int POW(ll a, int b = P - 2, ll x = 1) { for (; b; b >>= 1, a = a * a % P) if (b & 1) x = x * a % P; return x; }
//int INV(int a) { return a < maxn ? inv[a] : POW(a); }
namespace NTT {
    const int g = 3;
    vector<int> Omega(int L) {
        int wn = POW(g, P / L);
        vector<int> w(L); w[L >> 1] = 1;
        fp(i, L / 2 + 1, L - 1) w[i] = MUL(w[i - 1], wn);
        fd(i, L / 2 - 1, 1) w[i] = w[i << 1];
        return w;
    }
    auto W = Omega(1 << 21); // NOLINT
    void DIF(int *a, int n) {
        for (int k = n >> 1; k; k >>= 1)
            for (int i = 0, y; i < n; i += k << 1)
                fp(j, 0, k - 1)
                    y = a[i + j + k], a[i + j + k] = MUL(a[i + j] - y + P, W[k + j]), ADD(a[i + j], y);
    }
    void IDIT(int *a, int n) {
        for (int k = 1; k < n; k <<= 1)
            for (int i = 0, x, y; i < n; i += k << 1)
                fp(j, 0, k - 1)
                    x = a[i + j], y = MUL(a[i + j + k], W[k + j]),
                    a[i + j + k] = x - y < 0 ? x - y + P : x - y, ADD(a[i + j], y);
        int Inv = P - (P - 1) / n;
        fp(i, 0, n - 1) a[i] = MUL(a[i], Inv);
        reverse(a + 1, a + n);
    }
}
namespace Polynomial {
    using Poly = std::vector<int>;
 
    // mul/div int
    Poly &operator*=(Poly &a, int b) { for (auto &x : a) x = MUL(x, b); return a; }
    Poly operator*(Poly a, int b) { return a *= b; }
    Poly operator*(int a, Poly b) { return b * a; }
    Poly &operator/=(Poly &a, int b) { return a *= POW(b); }
    Poly operator/(Poly a, int b) { return a /= b; }
 
    // Poly add/sub
    Poly &operator+=(Poly &a, Poly b) {
        a.resize(max(a.size(), b.size()));
        fp(i, 0, b.size() - 1) ADD(a[i], b[i]);
        return a;
    }
    Poly operator+(Poly a, Poly b) { return a += b; }
    Poly &operator-=(Poly &a, Poly b) {
        a.resize(max(a.size(), b.size()));
        fp(i, 0, b.size() - 1) SUB(a[i], b[i]);
        return a;
    }
    Poly operator-(Poly a, Poly b) { return a -= b; }
 
    // Poly mul
    void DFT(Poly &a) { NTT::DIF(a.data(), a.size()); }
    void IDFT(Poly &a) { NTT::IDIT(a.data(), a.size()); }
    int norm(int n) { return 1 << (32 - __builtin_clz(n - 1)); }
    void norm(Poly &a) { if (!a.empty()) a.resize(norm(a.size()), 0); }
    Poly &dot(Poly &a, Poly &b) {
        fp(i, 0, a.size() - 1) a[i] = MUL(a[i], b[i]);
        return a;
    }
    Poly operator*(Poly a, Poly b) {
        int n = a.size() + b.size() - 1, L = norm(n);
        if (a.size() <= 8 || b.size() <= 8) {
            Poly c(n);
            fp(i, 0, a.size() - 1) fp(j, 0, b.size() - 1)
                c[i + j] = (c[i + j] + (ll) a[i] * b[j]) % P;
            return c;
        }
        a.resize(L), b.resize(L);
        DFT(a), DFT(b), dot(a, b), IDFT(a);
        return a.resize(n), a;
    }
     
    // Poly inv
    Poly Inv2k(Poly a) { // a.size() = 2^k
        int n = a.size(), m = n >> 1;
        if (n == 1) return {POW(a[0])};
        Poly b = Inv2k(Poly(a.begin(), a.begin() + m)), c = b;
        b.resize(n), DFT(a), DFT(b), dot(a, b), IDFT(a);
        fp(i, 0, n - 1) a[i] = i < m ? 0 : P - a[i];
        DFT(a), dot(a, b), IDFT(a);
        return move(c.begin(), c.end(), a.begin()), a;
    }
    Poly Inv(Poly a) {
        int n = a.size();
        norm(a), a = Inv2k(a);
        return a.resize(n), a;
    }
 
    // Poly div/mod
    Poly operator/(Poly a,Poly b){
        int k = a.size() - b.size() + 1;
        if (k < 0) return {0};
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        b.resize(k), a = a * Inv(b);
        a.resize(k), reverse(a.begin(), a.end());
        return a;
    }
    pair<Poly, Poly> operator%(Poly a, const Poly& b) {
        Poly c = a / b;
        a -= b * c, a.resize(b.size() - 1);
        return {c, a};
    }
     
    // Poly sqrt
    Poly Sqrt(Poly a) {
        int n = a.size(), k = norm(n);
        Poly b = {(new Cipolla(P))->sqrt(a[0]).first}, c;
        a.resize(k * 2, 0);
        for (int L = 2; L <= k; L <<= 1) {
            b.resize(2 * L, 0), c = Poly(a.begin(), a.begin() + L) * Inv(b);
            fp(i, 0, 2 * L - 1) b[i] = MUL(b[i] + c[i], (P + 1) / 2);
        }
        return b.resize(n), b;
    }
     
    // Poly calculus
    void Derivative(Poly &a) {
        fp(i, 1, a.size() - 1) a[i - 1] = MUL(i, a[i]);
        a.pop_back();
    }
}
using namespace Polynomial;
int n,m;
int getf(int x){
    if(x<0)return -getf(-x);
    if(x==f[x])return x;
    else return f[x]=getf(f[x]);
}
multiset<info> s;
bool check()
{
    int siz=s.size();
    vector<Poly> all; 
    for(auto [x,y]:s){
        Poly a(max(x,y)+1);
        a[x]++,a[y]++;
        all.push_back(a);
    }
    for(int j=0;j<15;j++){
        for(int i=0;i+(1<<j)<siz;i+=(1<<(j+1)))all[i]=all[i]*all[i+(1<<j)];
    }
    // cout<<"check = "<<endl;
    // for(auto [x,y]:s)cout<<x<<"/"<<y<<" ";;cout<<endl;
    // cout<<all[0][n]<<endl;
    return all[0][n]>0;
}
bool merge(int x,int y){//如果是x!=y将y取反(x>0 y>0)
    if(getf(x)==-getf(y))return false;
    if(getf(x)==getf(y))return true;
    x=getf(x),y=getf(y);
    if(x<0)x=-x,y=-y;
    if(siz[x][0]+(y>0?siz[y][0]:siz[-y][1])>n)return false;
    if(siz[x][1]+(y>0?siz[y][1]:siz[-y][0])>n)return false;
    // cout<<"merge x="<<x<<" y="<<y<<" s="<<s.size()<<endl;
    {
        s.extract(siz[x]);
        s.extract(siz[abs(y)]);
        if(y>0)siz[y][0]+=siz[x][0],siz[y][1]+=siz[x][1];
        else siz[-y][0]+=siz[x][1],siz[-y][1]+=siz[x][0];
        s.insert(siz[abs(y)]);
        if(check()){
            f[x]=y;return true;
        }
        s.extract(siz[abs(y)]);
        if(y>0)siz[y][0]-=siz[x][0],siz[y][1]-=siz[x][1];
        else siz[-y][0]-=siz[x][1],siz[-y][1]-=siz[x][0];
        s.insert(siz[x]);
        s.insert(siz[abs(y)]);
        return false;
    }    
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n*2;i++)f[i]=i,siz[i][0]=1,s.insert(siz[i]);
    vector<int> ans(n*2+1,0);
    vector<pair<int,int>> q(m);
    for(int i=0;i<m;i++){
        cin>>q[i].first>>q[i].second;
    }
    reverse(q.begin(),q.end());
    string anss;
    for(auto [x,y]:q){
        bool flag=merge(x,-y);

        if(!flag)merge(x,y);
        if(flag)anss.push_back('1');
        else anss.push_back('0');
        // cout<<"x="<<x<<" y="<<y<<" merge="<<flag<<endl;
    }
    // for(int i=1;i<=n;i++)cout<<
    vector<int> vis(n*2+1,0);
    vector<pair<vector<int>,vector<int>>>all;
    vector<vector<int>> dp(n*2+1,vector<int>(n+1));
    dp[0][0]=1;
    int p=0;
    for(int i=1;i<=n*2;i++)if(!vis[i]){
        vector<int> v0,v1;
        v0.push_back(i);
        p++;
        for(int j=i+1;j<=n*2;j++)if(abs(getf(i))==abs(getf(j))){
            if(getf(i)==-getf(j))v1.push_back(j);
            else v0.push_back(j);
            vis[j]=1;
        }
        all.emplace_back(v0,v1);
        for(int j=0;j<=n;j++){
            if(j>=v0.size())dp[p][j]|=dp[p-1][j-v0.size()];
            if(j>=v1.size())dp[p][j]|=dp[p-1][j-v1.size()];
        }
        // cout<<"v0 :";for(auto it:v0)cout<<it<<" ";;cout<<endl;
        // cout<<"v1 :";for(auto it:v1)cout<<it<<" ";;cout<<endl;
    }
    reverse(all.begin(),all.end());
    int now=n;
    // cout<<"???"<<endl;
    for(auto [v0,v1]:all){
        // cout<<"p="<<p<<" now="<<now<<endl;
        if(now>=v0.size()&&dp[p-1][now-v0.size()]){
            for(auto it:v0)ans[it]=0;
            for(auto it:v1)ans[it]=1;
            now-=v0.size();
        }
        else if(now>=v1.size()&&dp[p-1][now-v1.size()]){
            for(auto it:v0)ans[it]=1;
            for(auto it:v1)ans[it]=0;
            now-=v1.size();
        }
        p--;
    }
    assert(p==0&&now==0);
    int cnt[2]={0,0};
    for(int i=1;i<=2*n;i++)cnt[ans[i]]++;
    assert(cnt[0]==cnt[1]);
    for(int i=1;i<=2*n;i++)cout<<ans[i];;cout<<endl;
    // cout<<anss;
}

详细

Test #1:

score: 100
Accepted
time: 3ms
memory: 11332kb

input:

2 4
1 3
2 4
1 4
1 2

output:

0101

result:

ok Output is valid. OK

Test #2:

score: 0
Accepted
time: 6ms
memory: 11156kb

input:

3 7
2 5
1 3
4 6
2 6
4 5
2 4
5 6

output:

001101

result:

ok Output is valid. OK

Test #3:

score: 0
Accepted
time: 3ms
memory: 11284kb

input:

1 0

output:

10

result:

ok Output is valid. OK

Test #4:

score: 0
Accepted
time: 6ms
memory: 11108kb

input:

1 1
1 2

output:

01

result:

ok Output is valid. OK

Test #5:

score: 0
Accepted
time: 3ms
memory: 11144kb

input:

2 3
2 4
3 4
1 2

output:

0110

result:

ok Output is valid. OK

Test #6:

score: 0
Accepted
time: 3ms
memory: 11148kb

input:

3 8
4 6
3 5
1 4
2 4
1 6
1 2
3 4
4 5

output:

010101

result:

ok Output is valid. OK

Test #7:

score: 0
Accepted
time: 3ms
memory: 11108kb

input:

4 9
4 7
3 8
1 5
2 7
2 8
6 8
7 8
1 4
1 6

output:

01010110

result:

ok Output is valid. OK

Test #8:

score: 0
Accepted
time: 7ms
memory: 11284kb

input:

5 16
3 6
9 10
2 7
1 10
1 5
2 10
3 5
5 6
3 4
2 5
4 5
3 8
4 7
6 8
1 6
7 10

output:

0010111010

result:

ok Output is valid. OK

Test #9:

score: 0
Accepted
time: 3ms
memory: 11320kb

input:

6 13
4 5
2 9
3 8
4 8
4 11
10 12
3 4
3 9
5 11
2 8
5 10
5 8
1 11

output:

110110001001

result:

ok Output is valid. OK

Test #10:

score: 0
Accepted
time: 3ms
memory: 11420kb

input:

12 153
1 24
16 18
7 14
1 16
20 21
9 14
21 22
4 5
17 24
4 12
5 17
13 24
14 15
12 23
12 16
8 11
14 24
9 16
2 5
6 19
11 17
4 22
4 7
6 16
7 20
8 15
5 24
2 10
10 21
21 24
1 12
11 19
18 21
18 24
12 17
13 22
7 9
13 23
4 9
11 13
15 21
5 7
2 4
15 16
17 19
11 16
11 20
7 8
4 15
13 14
6 18
2 19
9 13
23 24
4 21
...

output:

000011100110010001111110

result:

ok Output is valid. OK

Test #11:

score: 0
Accepted
time: 63ms
memory: 12508kb

input:

259 33757
472 500
65 336
138 469
307 442
427 458
43 239
17 508
460 466
108 393
79 92
250 483
44 277
17 132
35 57
155 499
184 474
246 272
274 418
457 458
338 372
196 514
31 208
117 187
90 229
153 284
189 355
16 337
146 456
269 271
279 412
305 336
303 441
399 472
85 286
91 97
157 437
137 379
71 360
27...

output:

000111001101000110010001111000111111100000011101010011011101110001010010000001111000111010000011101001010001000011100101010011000101101100010101100101100101100010011000110100001110011000111101010100011001001110110101101101010101101001100110011110101001111011110001010001111101001110101101111001001100...

result:

ok Output is valid. OK

Test #12:

score: 0
Accepted
time: 786ms
memory: 19264kb

input:

811 265557
217 1153
383 1609
165 177
612 1602
1057 1428
37 436
135 1200
368 684
448 722
145 1583
325 1052
246 480
74 148
122 1111
1256 1327
304 1070
1285 1542
802 813
454 1563
265 1193
94 848
432 1156
429 1194
427 1230
1152 1406
1329 1355
702 845
591 1232
877 1288
1257 1549
340 659
1080 1333
910 137...

output:

001000000010111000100000000010100001011010111010110111111110000111010000101011011010001011001010111000001011000011011001000001011010001010000011100001010101100110010101011001101100100000100100001010000000100111110011110010001000000001011101100011100001000000101110100000001001100000011110101100100010...

result:

ok Output is valid. OK

Test #13:

score: -100
Time Limit Exceeded

input:

1691 323743
1246 2397
1445 2647
2010 2806
2001 2896
802 2258
2679 2976
2203 2875
2445 2698
137 3004
536 1800
2316 2520
594 1517
279 1558
1934 2871
57 1358
357 976
1764 2672
869 2137
1694 2201
491 1906
1177 1414
1304 1377
2454 2653
626 2637
1425 1677
620 876
1326 2085
404 874
626 1565
136 597
2885 31...

output:


result: