Logo Wy Online Judge

WyOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#497#93. 「NOIP2020」排水系统Pigsyy1006037ms12788kbC++239.1kb2025-04-25 17:23:352025-04-25 17:26:22

answer

#include <bits/stdc++.h>
using namespace std;
struct _int128 {
    unsigned long long low;
    long long high;
    bool sign;
    _int128(): low(0), high(0), sign(1) {}
    _int128(unsigned long long a, long long b, bool c = 1):
        low(a), high(b), sign(c) {}
    _int128(char a): low(abs(a)), high(0), sign(a >= 0) {}
    _int128(unsigned char a): low(a), high(0), sign(1) {}
    _int128(short a): low(abs(a)), high(0), sign(a >= 0) {}
    _int128(unsigned short a): low(a), high(0), sign(1) {}
    _int128(int a): low(abs(a)), high(0), sign(a >= 0) {}
    _int128(unsigned int a): low(a), high(0), sign(1) {}
    _int128(long long a): low(abs(a)), high(0), sign(a >= 0) {}
    _int128(unsigned long long a): low(a), high(0), sign(1) {}
    explicit operator char() {
        return (char)low;
    }
    explicit operator unsigned char() {
        unsigned char res = low;

        if (!sign)
            res = -res;

        return res;
    }
    explicit operator short() {
        return (short)low;
    }
    explicit operator unsigned short() {
        unsigned short res = low;

        if (!sign)
            res = -res;

        return res;
    }
    explicit operator int() {
        return (int)low;
    }
    explicit operator unsigned int() {
        unsigned int res = low;

        if (!sign)
            res = -res;

        return res;
    }
    explicit operator long long() {
        return (long long)low;
    }
    explicit operator unsigned long long() {
        unsigned long long res = low;

        if (!sign)
            res = -res;

        return res;
    }

    _int128 operator= (const _int128 &x) {
        low = x.low, high = x.high, sign = x.sign;
        return (*this);
    }
    bool operator!() const {
        return low == 0 && high == 0;
    }
    bool operator== (const _int128 &y) const {
        auto x = (*this);
        return x.sign == y.sign && x.low == y.low && x.high == y.high;
    }
    bool operator< (const _int128 &y) const {
        auto x = (*this);

        if (x.sign < y.sign)
            return 1;

        if (x.sign > y.sign)
            return 0;

        if (x.high < y.high)
            return 1;

        if (x.high > y.high)
            return 0;

        if (x.low < y.low)
            return 1;

        if (x.low > y.low)
            return 0;

        return 0;
    }
    bool operator<= (const _int128 &y) const {
        auto x = (*this);
        return x < y || x == y;
    }
    bool operator> (const _int128 &y) const {
        auto x = (*this);
        return !(x <= y);
    }
    bool operator>= (const _int128 &y) const {
        auto x = (*this);
        return !(x < y);
    }
    _int128 operator- () {
        auto t = (*this);
        t.sign ^= 1;
        return t;
    }
    _int128 add(_int128 x, _int128 y) {
        auto lo = x.low + y.low;
        auto hi = x.high + y.high;
        hi += lo < x.low;
        return _int128(lo, hi);
    }
    _int128 sub(_int128 x, _int128 y) {
        bool neg = false;

        if (x < y)
            swap(x, y), neg = true;

        auto lo = x.low - y.low;
        auto hi = x.high - y.high;
        hi -= x.low < y.low;
        return _int128(lo, hi, !neg);
    }
    _int128 operator+ (_int128 y) {
        auto x = (*this);

        if (x.sign ^ y.sign) {
            if (x < y)
                swap(x, y);

            return sub(x, y);
        } else {
            auto t = add(x, y);
            t.sign ^= !x.sign;
            return t;
        }
    }
    _int128 operator+= (const _int128 &x) {
        return (*this) = (*this) + x;
    }
    _int128 operator- (_int128 y) const {
        auto x = (*this);
        return x + (-y);
    }
    _int128 operator-= (const _int128 &x) {
        return (*this) = (*this) - x;
    }
    _int128 operator<< (const unsigned long long &y) const {
        auto x = (*this);

        if (y > 128)
            return _int128(0, 0);

        if (y >= 64) {
            return _int128(0, x.low << (y - 64), x.sign);
        } else {
            _int128 res = x;
            unsigned long long t = x.low >> (64 - y);
            res.high = (res.high << y) + t;
            res.low = res.low << y;
            return res;
        }
    }
    _int128 operator<<= (const unsigned long long &y) {
        return (*this) = (*this) << y;
    }
    _int128 operator>> (const unsigned long long &y) const {
        auto x = (*this);

        if (y > 128)
            return _int128(0, 0);

        if (y >= 64) {
            return _int128(x.high >> (y - 64), 0, x.sign);
        } else {
            _int128 res = x;
            unsigned long long t = x.high & ((1ll << y) - 1);
            res.low = (res.low >> y) + (t << (64 - y));
            res.high = res.high >> y;
            return res;
        }
    }
    _int128 operator>>= (const unsigned long long &y) {
        return (*this) = (*this) >> y;
    }
    _int128 operator& (_int128 y) {
        auto x = (*this);

        if (!x.sign)
            x.low = ~x.low, x.high = ~x.high;

        if (!y.sign)
            y.low = ~y.low, y.high = ~y.high;

        return _int128(x.low & y.low, abs(x.high & y.high), x.sign | y.sign);
    }
    _int128 operator| (_int128 y) {
        auto x = (*this);

        if (!x.sign)
            x.low = ~x.low, x.high = ~x.high;

        if (!y.sign)
            y.low = ~y.low, y.high = ~y.high;

        return _int128(x.low | y.low, abs(x.high | y.high), x.sign & y.sign);
    }
    _int128 operator^ (_int128 y) {
        auto x = (*this);

        if (!x.sign)
            x.low = ~x.low, x.high = ~x.high;

        if (!y.sign)
            y.low = ~y.low, y.high = ~y.high;

        return _int128(x.low ^ y.low, abs(x.high ^ y.high), !(x.sign ^ y.sign));
    }
    _int128 operator&= (const _int128 &x) {
        return (*this) = (*this) & x;
    }
    _int128 operator|= (const _int128 &x) {
        return (*this) = (*this) | x;
    }
    _int128 operator^= (const _int128 &x) {
        return (*this) = (*this) ^ x;
    }
    _int128 operator* (const _int128 &y) const {
        auto x = (*this);
        long long H = x.high * y.low + x.low * y.high, L = 0;
        unsigned int LH1 = x.low / (1ll << 32), LH2 = y.low / (1ll << 32);
        unsigned int LL1 = x.low, LL2 = y.low;
        H += (long long)LH1 * LH2, L += (unsigned long long)LL1 * LL2;
        _int128 res = _int128(L, H, !(x.sign xor y.sign));
        res += _int128((unsigned long long)LL1 * LH2) << 32;
        res += _int128((unsigned long long)LH1 * LL2) << 32;
        return res;
    }
    _int128 operator*= (const _int128 &y) {
        return (*this) = (*this) * y;
    }
    _int128 operator/ (_int128 y) const {
        auto x = (*this), z = _int128(1);

        while (y <= x)
            y <<= 1, z <<= 1;

        _int128 res = 0;

        while (y > 0) {
            if (x >= y) {
                x -= y;
                res |= z;
            }

            y >>= 1, z >>= 1;
        }

        res.sign = !(x.sign ^ y.sign);
        return res;
    }
    _int128 operator/= (const _int128 &y) {
        return (*this) = (*this) / y;
    }
    _int128 operator% (const _int128 &y) const {
        auto x = (*this);
        return x - x / y * y;
    }
};
typedef _int128 i128;
const int maxn=1e5+5;
i128 gcd(i128 a,i128 b)
{
	return !b?a:gcd(b,a%b);
}
i128 lcm(i128 a,i128 b)
{
	return a/gcd(a,b)*b;
}
struct Frac
{
	i128 fm,fz;
	Frac operator +(const Frac& b)const
	{
		Frac res;
		i128 fm1=fm,fz1=fz,fm2=b.fm,fz2=b.fz;
		if(!fm1)
		{
			res.fm=fm2;
			res.fz=fz2;
			return res;
		}
		if(!fm2)
		{
			res.fm=fm1;
			res.fz=fz1;
			return res;
		}
		i128 _lcm=lcm(fm1,fm2);
		fz1*=(_lcm/fm1);
		fz2*=(_lcm/fm2);
		res.fz=fz1+fz2;
		res.fm=_lcm;
		i128 _gcd=gcd(res.fz,res.fm);
		res.fz/=_gcd;
		res.fm/=_gcd;
		return res;
	}
	Frac operator /(const i128& x)const
	{
		Frac res;
		res.fm=fm*x;
		res.fz=fz;
		if(!fm)return res;
		i128 _gcd=gcd(res.fz,res.fm);
		res.fz/=_gcd;
		res.fm/=_gcd;
		return res;
	}
}val[maxn];
int n,m;
int indu[maxn];
int chudu[maxn];
int head[maxn];
struct EDGE
{
	int to,nxt;
}edge[maxn*5];
int cnt;
inline void add(int u,int to)
{
	edge[++cnt].to=to;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}
int que[maxn],qhead,qtail;
void topo()
{
	qhead=1,qtail=0;
	for(int i=1;i<=m;i++)
	{
		que[++qtail]=i;
		val[i].fz=val[i].fm=1;
	}
	while(qhead<=qtail)
	{
		int u=que[qhead++];
		for(int i=head[u];i;i=edge[i].nxt)
		{
			int to=edge[i].to;
			val[to]=val[to]+(val[u]/i128(chudu[u]));
			indu[to]--;
			if(!indu[to])
			{
				que[++qtail]=to;
			}
		}
	}
}
void write(i128 x)
{
	if(x>=10)
	{
		write(x/10);
	}
	putchar(int(x%10)^48);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		int di;
		scanf("%d",&di);
		int ai;
		for(int j=1;j<=di;j++)
		{
			scanf("%d",&ai);
			add(i,ai);
			indu[ai]++;
			chudu[i]++;
		}
	}
	topo();
	for(int i=1;i<=n;i++)
	{
		if(chudu[i]==0)
		{
			write(val[i].fz);
			putchar(' ');
			write(val[i].fm);
			putchar(10);
		}
	}
	return 0;
}

Details

小提示:点击横条可展开更详细的信息

Test #1:

score: 10
Accepted
time: 3ms
memory: 8724kb

input:

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

output:

1 1

result:

ok 2 tokens

Test #2:

score: 10
Accepted
time: 7ms
memory: 7268kb

input:

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

output:

2 15
8 15
1 3

result:

ok 6 tokens

Test #3:

score: 10
Accepted
time: 0ms
memory: 9228kb

input:

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

output:

3 20
2 5
9 20

result:

ok 6 tokens

Test #4:

score: 10
Accepted
time: 11ms
memory: 9268kb

input:

1000 1
5 2 3 4 5 468
5 6 7 8 9 72
5 10 11 12 13 658
5 14 15 16 17 100
5 18 19 20 21 129
5 22 23 24 2...

output:

1 625
1 625
1 625
1 625
1 625
1 625
1 625
1 3125
1 3125
2 3125
3 3125
2 3125
47 37500
1 2500
1 2500
...

result:

ok 636 tokens

Test #5:

score: 10
Accepted
time: 15ms
memory: 9020kb

input:

1000 1
5 2 3 4 5 257
5 6 7 8 9 948
5 10 11 12 13 633
5 14 15 16 17 1000
5 18 19 20 21 105
5 22 23 24...

output:

1 625
1 625
6 625
2 625
1 625
1 625
1 625
1 625
1 625
1 625
1 500
1 1875
1 1250
1 2500
9 6250
1 2500...

result:

ok 626 tokens

Test #6:

score: 10
Accepted
time: 17ms
memory: 8788kb

input:

1000 1
5 2 3 4 5 799
5 6 7 8 9 587
5 10 11 12 13 694
5 14 15 16 17 865
5 18 19 20 21 10
5 22 23 24 2...

output:

1 625
1 625
1 625
1 625
1 625
1 625
2 625
6 625
9 6250
9 2500
1 2000
9 10000
1 2500
1 2500
1 2500
2 ...

result:

ok 652 tokens

Test #7:

score: 10
Accepted
time: 1101ms
memory: 12788kb

input:

100000 1
5 2 3 4 5 7783
5 6 7 8 9 21991
5 10 11 12 13 45651
5 14 15 16 17 56745
5 18 19 20 21 84002
...

output:

1 15625
1 15625
1 15625
1 15625
1 15625
1 78125
1 62500
1 78125
1 78125
1 78125
1 78125
1 78125
2 78...

result:

ok 93056 tokens

Test #8:

score: 10
Accepted
time: 1302ms
memory: 11180kb

input:

100000 1
5 2 3 4 5 6025
5 6 7 8 9 32221
5 10 11 12 13 39240
5 14 15 16 17 55392
5 18 19 20 21 69386
...

output:

1 12500
1 15625
1 15625
1 15625
1 15625
1 12500
1 15625
1 12500
1 12500
1 15625
1 15625
1 15625
1 12...

result:

ok 84746 tokens

Test #9:

score: 10
Accepted
time: 1785ms
memory: 11740kb

input:

100000 10
5 11 12 13 14 15
3 66 67 68
4 96 97 98 99
5 1274 1643 2223 2242 2626
5 5407 8119 10748 198...

output:

1 48828125
2538341 10546875000
15673 2343750000
759673 2343750000
54145169317349 3023308800000000000...

result:

ok 64816 tokens

Test #10:

score: 10
Accepted
time: 1796ms
memory: 12716kb

input:

100000 10
5 11 12 13 14 15
3 66 67 68
4 98 99 100 101
5 193 213 239 613 1656
5 187 259 453 513 3129
...

output:

1 48828125
1 48828125
191216299 675000000000
3778533703 48600000000000
214192764230063 3627970560000...

result:

ok 64158 tokens