求助玄学时间复杂度
  • 板块学术版
  • 楼主C6H6
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/7/11 20:41
  • 上次更新2023/11/3 10:27:15
查看原帖
求助玄学时间复杂度
569516
C6H6楼主2023/7/11 20:41

rt,这是蒟蒻用普通线段树写的DDP,加上一堆常数优化后卡过了这题

#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
long long a[200010];
bool flg[200010];
long long inv[200];
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++)
const int MAXSIZE = 1 << 22;
char buf[MAXSIZE], *p1, *p2; 
void read(){}
template <class T1, class ...T2>
void read(T1& ret, T2&... rest){
    ret = 0; char c; bool f = false;
    while (!isdigit(c = gc() ) ) f = c == '-';
    while(isdigit(c) ){
    	ret = (ret << 3) + (ret << 1) + (c ^ '0');
    	c = gc();
	}
    if(f) ret = -ret;
    read(rest...);
}
char pbuf[MAXSIZE],*pp=pbuf;
inline void pc(const char &c){
	*pp++=c;
}
inline void print(const long long ret){
	static int sta[35];
	long long x = ret, top = 0;
	bool f = (ret < 0);
	if(ret < 0) x = -x;
	do{sta[top++] = x % 10, x /= 10; }while(x);
	if(f) pc('-');
	while(top) pc(sta[--top] + 48);
}
struct matrix{
    long long a[3][3];
    matrix(){
        memset(a, 0, sizeof(a));
        for(int i = 0; i < 3; i++) a[i][i] = 1;
    }
}c;
struct segment_tree{
    int l, r;
    matrix f;
}t[800010];
inline long long qmi(long long a, long long b){
	long long ret = 1;
	while(b){
		if(b & 1) ret = ret * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return ret;
}
inline matrix matrix_mul(matrix a, matrix b){
    memset(c.a, 0, sizeof(c.a));
	for(int i = 0; i < 3; i++)
		for(int j = 0; j < 3; j++)
			for(int k = 0; k < 3; k++)
				c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
    return c;
}
inline void update(int x){
    int ls = (x << 1), rs = ls | 1;
    if(t[rs].f.a[2][2] != 1) t[rs].f = matrix();
    if(t[ls].f.a[2][2] != 1) t[ls].f = matrix();
    t[x].f = matrix_mul(t[ls].f, t[rs].f);
}
void build(int l, int r, int p){
    t[p].l = l;
    t[p].r = r;
    if(l == r){
        long long pi1 = (100 - a[l]) * inv[100] % mod;
        long long pi =  a[l] * inv[100] % mod;
        long long npi = qmi(pi, mod - 2);
        long long ATP[3][3] = {
            {1, 0, 0},
            {pi1 * (flg[l] == 0) * npi % mod, (flg[l] == 0) * npi, 0},
            {(pi1 * npi + 1) % mod, npi, 1}
        };
        for(int j = 0; j < 3; j++)
            for(int k = 0; k < 3; k++)
                t[p].f.a[j][k] = ATP[j][k];
        return;
    }
    int mid = (l + r) >> 1, ls = (p << 1), rs = ls | 1;
    build(l, mid, ls);
    build(mid + 1, r, rs);
    update(p);
}
void modify(int l, int r, int p, int x){
    if(l == r){
        long long pi1 = (100 - a[l]) * inv[100] % mod;
        long long pi =  a[l] * inv[100] % mod;
        long long npi = qmi(pi, mod - 2);
        long long ATP[3][3] = {
            {1, 0, 0},
            {pi1 * (flg[l] == 0) * npi % mod, (flg[l] == 0) * npi, 0},
            {(pi1 * npi + 1) % mod, npi, 1}
        };
        for(int j = 0; j < 3; j++)
            for(int k = 0; k < 3; k++)
                t[p].f.a[j][k] = ATP[j][k];
        return;
    }
    int mid = (l + r) >> 1, ls = p << 1, rs = ls | 1;
    if(x <= mid) modify(l, mid, ls, x);
    else modify(mid + 1, r, rs, x);
    update(p);
}
matrix query(int l, int r, int p){
    if(l <= t[p].l && t[p].r <= r) return t[p].f;
    int mid = (l + r) >> 1, ls = p << 1, rs = ls | 1;
    matrix ret = matrix();
    if(l <= mid) ret = matrix_mul(ret, query(l, mid, ls));
    if(mid < r) ret = matrix_mul(ret, query(mid + 1, r, rs));
    return ret;
}
int main(){
    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; i++) read(a[i]);
    for(int i = 1; i <= 100; i++) inv[i] = qmi(i, mod - 2);
    build(1, n, 1);
    while(q--){
        int x;
        read(x);
        flg[x] ^= 1;
        modify(1, n, 1, x);
        matrix tmp;
        memset(tmp.a, 0, sizeof(tmp.a));
        int ATP[3][3] = {
            {0, 0, 1},
            {0, 0, 0},
            {0, 0, 0}
        };
        for(int i = 0; i < 3; i++)
            for(int j = 0; j < 3; j++)
                tmp.a[i][j] = ATP[i][j];
        tmp = matrix_mul(tmp, query(1, n, 1));
        print(tmp.a[0][0]);
        pc('\n');
    }
    fwrite(pbuf,1,pp-pbuf,stdout);


    return 0;
}

然而我用zkw线段树却T了

#include <bits/stdc++.h>
using namespace std;
#define int unsigned
const int mod = 998244353;
int a[200010];
bool flg[200010];
long long inv[110];
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++)
const int MAXSIZE = 1 << 22;
char buf[MAXSIZE], *p1, *p2; 
void read(){}
template <class T1, class ...T2>
void read(T1& ret, T2&... rest){
    ret = 0; char c; bool f = false;
    while (!isdigit(c = gc() ) ) f = c == '-';
    while(isdigit(c) ){
    	ret = (ret << 3) + (ret << 1) + (c ^ '0');
    	c = gc();
	}
    if(f) ret = -ret;
    read(rest...);
}
char pbuf[MAXSIZE],*pp=pbuf;
inline void pc(const char &c){
	*pp++=c;
}
inline void print(const long long ret){
	static int sta[35];
	long long x = ret, top = 0;
	bool f = (ret < 0);
	if(ret < 0) x = -x;
	do{sta[top++] = x % 10, x /= 10; }while(x);
	if(f) pc('-');
	while(top) pc(sta[--top] + 48);
}
struct matrix{
    long long a[3][3];
    matrix(){
        memset(a, 0, sizeof(a));
        for(int i = 0; i < 3; i++) a[i][i] = 1;
    }
}c;
inline long long qmi(long long a, long long b){
	long long ret = 1;
	while(b){
		if(b & 1) ret = ret * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return ret;
}
inline matrix matrix_mul(const matrix &a, const matrix &b){
    if(__builtin_expect(a.a[2][2] != 1 && a.a[0][2] != 1, 0)) return b;
    if(__builtin_expect(b.a[2][2] != 1 && b.a[0][2] != 1, 0)) return a;
    memset(c.a, 0, sizeof(c.a));
	for(int i = 0; i < 3; i++)
		for(int k = 0; k < 3; k++)
			for(int j = 0; j < 3; j++)
				c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
    return c;
}
matrix t[800010];
int siz = 1;
inline void build(int n){
    for(; siz <= n + 1; siz <<= 1);
    for(int i = siz + 1; i <= siz + n; i++){
        long long pi1 = (100 - a[i - siz]) * inv[100] % mod;
        long long pi =  a[i - siz] * inv[100] % mod;
        long long npi = qmi(pi, mod - 2);
        long long ATP[3][3] = {
            {1, 0, 0},
            {pi1 * (flg[i - siz] == 0) * npi % mod, (flg[i - siz] == 0) * npi, 0},
            {(pi1 * npi + 1) % mod, npi, 1}
        };
        for(int j = 0; j < 3; j++)
            for(int k = 0; k < 3; k++)
                t[i].a[j][k] = ATP[j][k];
    }
    for(int i = siz - 1; i >= 1; i--) t[i] = matrix_mul(t[i << 1], t[i << 1 | 1]);
}
inline void add(int x){
    long long pi1 = (100 - a[x]) * inv[100] % mod;
    long long pi =  a[x] * inv[100] % mod;
    long long npi = qmi(pi, mod - 2);
    long long ATP[3][3] = {
        {1, 0, 0},
        {pi1 * (flg[x] == 0) * npi % mod, (flg[x] == 0) * npi, 0},
        {(pi1 * npi + 1) % mod, npi, 1}
    };
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++)
            t[x + siz].a[i][j] = ATP[i][j];
    x += siz;
    x >>= 1;
    for(; x; x >>= 1) t[x] = matrix_mul(t[x << 1], t[x << 1 | 1]);
}
inline matrix query(int l, int r){
    matrix ret = matrix();
    for(l = l + siz - 1, r = r + siz + 1; r ^ l ^ 1; l >>= 1, r >>= 1){
        if(~l & 1) ret = matrix_mul(ret, t[l ^ 1]);
        if(r & 1) ret = matrix_mul(ret, t[r ^ 1]);
    }
    return ret;
}
signed main(){
    int n, q;
    read(n, q);
    for(int i = 1; i <= n; i++) read(a[i]);
    for(int i = 1; i <= 100; i++) inv[i] = qmi(i, mod - 2);
    build(n);
    while(q--){
        int x;
        read(x);
        flg[x] ^= 1;
        add(x);
        matrix tmp;
        memset(tmp.a, 0, sizeof(tmp.a));
        tmp.a[0][2] = 1;
        tmp = matrix_mul(tmp, query(1, n));
        print(tmp.a[0][0]);
        pc('\n');
    }
    fwrite(pbuf,1,pp-pbuf,stdout);
    return 0;
}

所以是zkw的问题还是我写挂了?请求大佬指点

2023/7/11 20:41
加载中...