2019 wannafly winter camp day5-8代码库

本来是8天代码放一起的,但是太麻烦了,还是分成了2个博客放。

day5

H div2

//H
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int  MXN = 2e6 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
LL n, m;
std::vector<int> mp[MXN];
LL siz[MXN];
LL ans;
void dfs(int u,int ba) {
    siz[u] = 1;
    for(auto v: mp[u]) {
        if(v == ba) continue;
        dfs(v, u);
        siz[u] += siz[v];
        ans += siz[v] *(n*m-siz[v])%mod;
        ans = (ans%mod + mod)%mod;
    }
}
int main(){
    scanf("%lld%lld", &n, &m);
    for(int i = 1, a, b; i < n; ++i) {
        scanf("%d%d", &a, &b);
        for(int j = 0; j < m; ++j) {
            mp[a+j*n].push_back(b+j*n);
            mp[b+j*n].push_back(a+j*n);
        }
    }
    for(int i = 1, a, b, u, v; i < m; ++i) {
        scanf("%d%d%d%d", &a, &b, &u, &v); --a, --b;
        mp[a*n+u].push_back(b*n+v);
        mp[b*n+v].push_back(a*n+u);
    }
    dfs(1, 1);
    printf("%lld\n", ans);
    return 0;
}

F div2

//F
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int  MXN = 2e6 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m;
LL dp[1<<16][16];
char s[MXN];
int get_num(int x) {
    bitset<40> sb(x);
    return sb.count();
}
int main(){
    scanf("%d%s", &n, s+1);
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < n; ++i) {
        dp[1<<i][i] = 1;
    }
    int sta = 1<<n;
    for(int t = 1; t < sta; ++t) {
        for(int i = 0; i < n; ++i) {
            if(!(t & (1 << i))) continue;
            for(int j = 0; j < n; ++j) {
                if(i == j) continue;
                if(!(t&(1<<j))) continue;
                int old = t^(1<<i);
                if(dp[old][j] == -1) continue;
                int h = get_num(old);
                if(h == 0) continue;
                if(s[h] == '1' && ((j+1)*2 == i+1||(i+1)*2==j+1)) {
                    //if(dp[t][i] == -1) dp[t][i] = 0;
                    dp[t][i] += dp[old][j];
                }else if(s[h] == '0' && (j+1)*2!=i+1&&(i+1)*2!=j+1){
                    //if(dp[t][i] == -1) dp[t][i] = 0;
                    dp[t][i] += dp[old][j];
                }
                if(dp[t][i] >= mod) dp[t][i] %= mod;
            }
        }
    }
    LL ans = 0;
    for(int i = 0; i < n; ++i) {
        if(dp[sta-1][i] == -1) continue;
        ans = (ans + dp[sta-1][i]) % mod;
    }
    printf("%lld\n", ans);
    return 0;
}

J div1

//J
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
#define db LL
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;
#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))
const int  MXN = 1e5 + 6;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
int n, m;
struct P {
    db x, y;
    P(){};
    P(db _x, db _y):x(_x),y(_y){}
    P operator+(P p){return {x+p.x,y+p.y};}
    P operator-(P p){return {x-p.x,y-p.y};}
    db dot(P p) {return x*p.x+y*p.y;}
    db det(P p) {return x*p.y-y*p.x;}
};
inline int sign(db a) {return a < -eps?-1:a>eps;}
inline int cmp(db a, db b) {return sign(a-b);}

bool intersect(db l1, db r1, db l2, db r2) {
    if(l1 > r1) swap(l1, r1);if(l2 > r2) swap(l2, r2);
    return !(cmp(r1,l2)==-1||cmp(r2,l1)==-1);
}
bool isSS(P p1, P p2, P q1, P q2) {
    return intersect(p1.x,p2.x,q1.x,q2.x)&&intersect(p1.y,p2.y,q1.y,q2.y)&&
    crossOp(p1,p2,q1)*crossOp(p1,p2,q2)<=0&&crossOp(q1,q2,p1)*crossOp(q1,q2,p2)<=0;
}
bool isSS_strict(P p1, P p2, P q1, P q2) {
    return crossOp(p1,p2,q1)*crossOp(p1,p2,q2)<0&&crossOp(q1,q2,p1)
    *crossOp(q1,q2,p2) < 0;
}
bool isMiddle(db a, db m, db b) {
    return sign(a-m)==0||sign(b-m)==0||(a<m!=b<m);
}
bool isMiddle(P a, P m, P b) {
    return isMiddle(a.x,m.x,b.x)&&isMiddle(a.y,m.y,b.y);
}
bool onSeg(P p1, P p2, P q) {
    return crossOp(p1,p2,q) == 0 && isMiddle(p1,q,p2);
}
bool ojbk(P p1, P p2, P q1, P q2) {
    P p = p2 - p1;
    P q = q2 - q1;
    if(q.det(p) == 0) return 1;
    return 0;
}
double rad(P p1, P p2) {
    return atan2(p1.det(p2),p1.dot(p2));
}
bool xielv(P p1, P p2, P q1, P q2) {
    P p = p2 - p1;
    P q = q2 - q1;
    if(q.det(p) == 0 && cmp(rad(p, q), 0) == 0) return 1;
    return 0;
}
struct lp {
    int a, b;
}cw[MXN];
LL x[MXN], y[MXN];
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i) {
        scanf("%d%d", &cw[i].a, &cw[i].b);
    }
    for(int i = 1; i <= n; ++i) {
        scanf("%lld%lld", &x[i], &y[i]);
    }
    int cnt = 0;
    for(int i = 1; i <= m; ++i) {
        for(int j = i + 1; j <= m; ++j) {
            P p1 = {x[cw[i].a],y[cw[i].a]};
            P p2 = {x[cw[i].b],y[cw[i].b]};
            P q1 = {x[cw[j].a],y[cw[j].a]};
            P q2 = {x[cw[j].b],y[cw[j].b]};
            //printf("%d %d %d %d\n", cw[i].a, cw[i].b, cw[j].a, cw[j].b);
            //printf("%lld %lld\n", q2.x,q2.y);
            if(isSS(p1,p2,q1,q2)) {
                if(cw[i].a==cw[j].a || cw[i].a==cw[j].b||cw[i].b==cw[j].a||cw[i].b==cw[j].b) {
                    //printf("%lld %lld %lld %lld %lld %lld %lld %lld\n", p1.x,p1.y,p2.x,p2.y,q1.x,q1.y,q2.x,q2.y);
                    if(cw[i].a==cw[j].a&&xielv(p1,p2,q1,q2)) cnt++;
                    if(cw[i].a==cw[j].b&&xielv(p1,p2,q2,q1)) cnt++;
                    if(cw[i].b==cw[j].a&&xielv(p2,p1,q1,q2)) cnt++;
                    if(cw[i].b==cw[j].b&&xielv(p2,p1,q2,q1)) cnt++;
                }else cnt++;
            }
        }
    }
    printf("%d\n", cnt);
    return 0;
}

I div1

//I
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int MXN = 1e6 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, q, x;
int ar[MXN];
int sum1[MXN<<2], sum2[MXN<<2], flag[MXN<<2];
LL num1[MXN], num2[MXN];
void push_up(int rt) {
    sum1[rt] = sum1[rt<<1] + sum1[rt<<1|1];
    sum2[rt] = sum2[rt<<1] + sum2[rt<<1|1];
}
void build(int l,int r,int rt) {
    flag[rt] = -1;
    if(l == r) {
        if(ar[l] > x) sum2[rt] = 1;
        else sum1[rt] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid,rt<<1); build(mid+1, r,rt<<1|1);
    push_up(rt);
}
void push_down(int l,int mid,int r,int rt) {
    if(flag[rt] == -1) return ;
    flag[rt<<1] = flag[rt];
    flag[rt<<1|1] = flag[rt];
    if(flag[rt] == 0) {
        sum1[rt<<1] = mid-l+1;
        sum1[rt<<1|1] = r-mid;
        sum2[rt<<1] = 0;
        sum2[rt<<1|1] = 0;
    }else {
        sum1[rt<<1] = 0;
        sum1[rt<<1|1] = 0;
        sum2[rt<<1] = mid-l+1;
        sum2[rt<<1|1] = r-mid;
    }
    flag[rt] = -1;
}
void update(int L, int R,int v,int l,int r,int rt) {
    if(L > R) return ;
    if(L <= l && r <= R) {
        if(v == 0) sum1[rt] = r - l + 1,sum2[rt] = 0;
        else sum2[rt] = r - l + 1,sum1[rt] = 0;
        flag[rt] = v;
        return;
    }
    int mid = (l + r) >> 1;
    push_down(l, mid, r, rt);
    if(L > mid) update(L, R, v,mid+1,r,rt<<1|1);
    else if(R <= mid) update(L,R,v,l,mid,rt<<1);
    else {
        update(L,mid,v,l,mid,rt<<1), update(mid+1,R,v,mid+1,r,rt<<1|1);
    }
    push_up(rt);
}
int query1(int L,int R,int l,int r,int rt,int id) {
    if(L > R) return 0;
    if(L <= l && r <= R) {
        if(id == 0)return sum1[rt];
        return sum2[rt];
    }
    int mid = (l + r) >> 1;
    push_down(l, mid, r, rt);
    if(L > mid) return query1(L, R, mid+1,r,rt<<1|1,id);
    else if(R <= mid) return query1(L,R,l,mid,rt<<1,id);
    else {
        return query1(L,mid,l,mid,rt<<1,id) + query1(mid+1,R,mid+1,r,rt<<1|1,id);
    }
}
int main(){
    scanf("%d%d%d", &n, &q, &x);
    for(int i = 1; i <= n; ++i) scanf("%d", &ar[i]);
    int cnt1 = 0, cnt2 = 0;
    for(int i = 1; i <= n; ++i) {
        if(ar[i] <= x) ++ cnt1, num1[cnt1] = num1[cnt1-1]+ar[i];
        else ++ cnt2, num2[cnt2] = num2[cnt2-1]+ar[i];
    }
    build(1, n, 1);
    int p, l, r;
    while(q --) {
        scanf("%d%d%d", &p, &l, &r);
        if(p == 1) {
            int p0 = query1(1,l-1,1,n,1,0), p1 = query1(1,r,1,n,1,0);
            int q0 = query1(1,l-1,1,n,1,1), q1 = query1(1,r,1,n,1,1);
            printf("%lld\n", num1[p1] - num1[p0] + num2[q1] - num2[q0]);
        }else if(p == 2) {
            int sb1 = query1(l,r,1,n,1,0);
            if(sb1) update(l,l+sb1-1,0,1,n,1);
            update(l+sb1,r,1,1,n,1);
        }else {
            int sb2 = query1(l,r,1,n,1,1);
            if(sb2) update(l,l+sb2-1,1,1,n,1);
            update(l+sb2,r,0,1,n,1);
        }
    }
    return 0;
}

D div1

//D杨栩
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;
const int  MXN = 2e6 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n;
int vis[15][15];
int visr[15][15];
int visc[15][15];
int needr[15];
int needc[15];
int nowrx[15],nowcx[15];// di  i 行 第一个x的纵坐标  竖 横坐标
int haverx[15],havecx[15];
int nowc[15],nowr[15];
int totc[15],totr[15];
int flag = 0;
int sum;
bool check() {
    for(int i=1; i<=n; i++) {
        if(havecx[i]!=2 || haverx[i]!=2) {
            return 0;
        }
    }
    return 1;
}
void dfs(int x,int y) {
    //cout<<"now:"<<x<<","<<y<<",,"<<flag<<endl;
    if(haverx[x]==0 && sum-totr[x]<needr[x]) return;
    if(havecx[y]==0 && sum-totc[y]<needc[y]) return;
    if(flag ) return ;
    if(x==n+1) {
        if(check())
            flag = 1;
        //cout<<"haha:"<<flag<<endl;
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                if(vis[i][j]!=-1) {
                    printf("%d",vis[i][j]);
                } else {
                    printf("X");
                }
            }
            puts("");
        }
        return ;
    }
//    for(int i=1; i<=n; i++) {
//        for(int j=1; j<=n; j++) {
//            if(vis[i][j]!=-1) {
//                printf("%d",vis[i][j]);
//            } else {
//                printf("X");
//            }
//        }
//        puts("");
//    }
    // 判断是否可放x
    if(haverx[x]==0 &&havecx[y]==0) {
        nowrx[x]=y;
        nowcx[y]=x;
        havecx[y]++;
        haverx[x]++;
        vis[x][y]=-1;
        if(y+1>n) {
            if(haverx[x]==2)
                dfs(x+1,1);
        } else {
            dfs(x,y+1);
        }
        vis[x][y]=0;
        nowrx[x]=0;
        nowcx[y]=0;
        havecx[y]--;
        haverx[x]--;
    }
    // 横有了一个x 竖没有x
    else if(haverx[x]==1 && havecx[y]==0) {
        int cnt = nowr[x];//getnum(nowrx[x],y,x,1);
        //cout<<"cnt:"<<cnt<<endl;
        // 第 i 行 两个x之间的属的和满足ri
        if(cnt==needr[x]) {
            havecx[y]++;
            haverx[x]++;
            nowcx[y]=x;
            vis[x][y]=-1;
            if(y+1>n) {
                if(haverx[x]==2)
                    dfs(x+1,1);
            } else {
                dfs(x,y+1);
            }
            vis[x][y]=0;
            havecx[y]--;
            haverx[x]--;
            nowcx[y]=0;
        }
    }
    // 竖有了一个x 横没有x
    else if(haverx[x]==0 && havecx[y]==1) {
        int cnt = nowc[y];//getnum(nowcx[y],x,y,0);
        // 第 i 行 两个x之间的属的和满足ri
        if(cnt==needc[y]) {
            havecx[y]++;
            haverx[x]++;
            nowrx[x]=y;
            vis[x][y]=-1;
            if(y+1>n) {
                if(haverx[x]==2)
                    dfs(x+1,1);
            } else {
                dfs(x,y+1);
            }
            vis[x][y]=0;
            havecx[y]--;
            haverx[x]--;
            nowrx[x]=0;
        }
    }// 横竖都有一个
    else {
        int cnt1 = nowr[x];//getnum(nowrx[x],y,x,1);
        int cnt2 = nowc[y];//getnum(nowcx[y],x,y,0);
        if(cnt1 == needr[x] && cnt2 == needc[y]) {
            havecx[y]++;
            haverx[x]++;
            vis[x][y]=-1;
            if(y+1>n) {
                if(haverx[x]==2)
                    dfs(x+1,1);
            } else {
                dfs(x,y+1);
            }
            vis[x][y]=0;
            havecx[y]--;
            haverx[x]--;
        }
    }
    for(int i=1; i<=n-2; i++) {
        int cnt1 = 0;
        if(haverx[x]==1) {
            cnt1 =nowr[x];//getnum(nowrx[x],y,x,1);

            if(cnt1+i>needr[x]) continue;
            //cout<<"cnt1+i:"<<cnt1+i<<"vs"<<needr[x]<<endl;
        }
        int cnt2 = 0;
        if(havecx[y]==1) {
            cnt2 = nowc[y];//getnum(nowcx[y],x,y,0);
            if(cnt2+i>needc[y]) continue;
        }
        if(visc[y][i]==0 && visr[x][i]==0 ) {
            visc[y][i]=1;
            visr[x][i]=1;
            vis[x][y]=i;
            totc[y]+=i;
            totr[x]+=i;
            if(haverx[x]==1) {
                nowr[x]+=i;
            }
            if(havecx[y]==1) {
                nowc[y]+=i;
            }
            if(y+1>n) {
                if(haverx[x]==2)
                    dfs(x+1,1);
            } else {
                dfs(x,y+1);
            }
            if(haverx[x]==1) {
                nowr[x]-=i;
            }
            if(havecx[y]==1) {
                nowc[y]-=i;
            }
            totc[y]-=i;
            totr[x]-=i;
            visc[y][i]=0;
            visr[x][i]=0;
            vis[x][y]=0;
        }
    }
}
void init() {
    flag = 0;
    memset(vis,0,sizeof vis);
    memset(visr,0,sizeof visr);
    memset(visc,0,sizeof visc);
    memset(needr,0,sizeof needr);
    memset(needc,0,sizeof needc);
    memset(nowrx,0,sizeof nowrx);
    memset(nowcx,0,sizeof nowcx);
    memset(haverx,0,sizeof haverx);
    memset(havecx,0,sizeof havecx);
    memset(nowc,0,sizeof nowc);
    memset(nowr,0,sizeof nowr);
    memset(totc,0,sizeof totc);
    memset(totr,0,sizeof totr);
    sum=0;
    for(int i=1; i<=n-2; i++) {
        sum+=i;
    }
//    cout<<sum<<endl;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {

        scanf("%d",&n);
        init();
        for(int i=1; i<=n; i++) {
            scanf("%d",&needr[i]);
        }
        for(int j=1; j<=n; j++) {
            scanf("%d",&needc[j]);
        }
        dfs(1,1);
        if(T)
            puts("");
    }
}

C div1

//C
题解:https://blog.csdn.net/qq_39599067/article/details/86650060
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int MXN = 1e6 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, q;
int ar[MXN], num[MXN];
LL sum[MXN];
struct QUERY {
    int l, r, k;
    LL ans;
}cw[MXN];
struct lp {
    int l, r, cnt;
    LL sum;
}node[MXN*16];
int inde, Root[MXN];
void z_update(int old, int &cur, int val, LL L, LL R) {
    cur = ++ inde;
    node[cur] = node[old];
    if(L == R) {
        node[cur].sum += val - val/2;
        ++ node[cur].cnt;
        return;
    }
    LL mid = (L + R) / 2;
    if(val <= mid) z_update(node[old].l, node[cur].l, val, L, mid);
    else z_update(node[old].r, node[cur].r, val, mid+1, R);
    node[cur].sum = node[node[cur].l].sum + node[node[cur].r].sum;
    node[cur].cnt = node[node[cur].l].cnt + node[node[cur].r].cnt;
}
LL z_query(int k, int old, int cur, LL L, LL R) {
    if(L == R) {
        return (LL)k*(L-L/2);
    }
    LL mid = (L + R) / 2;
    int tmp = node[node[cur].r].cnt - node[node[old].r].cnt;
    if(k <= tmp) {
        return z_query(k, node[old].r, node[cur].r, mid + 1, R);
    }else {
        return node[node[cur].r].sum - node[node[old].r].sum
        + z_query(k-tmp, node[old].l, node[cur].l, L, mid);
    }
}
/*LL query(int k, int old, int cur, int L, LL R) {
    printf("%d %lld %lld\n", k, node[cur].sum, node[old].sum);
    if(L == R) {
        printf("*%d %d\n", L,k*(L-L/2));
        return (LL)k*(L-L/2);
    }
    LL mid = (L + R) / 2;
    int tmp = node[node[cur].r].cnt - node[node[old].r].cnt;
    printf("%d %d %d %d %lld\n", k, tmp, node[node[old].r].cnt,node[node[cur].r].cnt,node[node[cur].r].sum - node[node[old].r].sum);
    if(k <= tmp) {
        return query(k, node[old].r, node[cur].r, mid + 1, R);
    }else {
        return node[node[cur].r].sum - node[node[old].r].sum
        + query(k-tmp, node[old].l, node[cur].l, L, mid);
    }
}*/
int main(){
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; ++i) scanf("%d", ar+i), sum[i]=sum[i-1]+ar[i];
    for(int i = 1; i <= q; ++i) {
        scanf("%d%d%d", &cw[i].l, &cw[i].r, &cw[i].k);
        cw[i].ans = sum[cw[i].r] - sum[cw[i].l-1];
    }
    LL L, R;
    for(int T = 30; T >= 0; --T) {
        L = 1LL<<T, R = 2LL<<T, inde = 0;
        node[0].l = node[0].r = node[0].sum = node[0].cnt = 0;
        for(int i = 1; i <= n; ++i) if(ar[i]>>T&1) {
            z_update(Root[i-1], Root[i], ar[i], L, R);
            //if(T == 2) printf("[%d %d]\n", i, ar[i]);
            sum[i] = sum[i-1] + ar[i] - ar[i]/2; num[i] = num[i-1] + 1;
        }else Root[i] = Root[i-1], sum[i] = sum[i-1], num[i] = num[i-1];
        //printf("T = %d\n", T);
        for(int i = 1, tmp; i <= q; ++i) {
            if(cw[i].k == 0) continue;
            if(cw[i].k >= num[cw[i].r] - num[cw[i].l-1]) {
                cw[i].k -= num[cw[i].r] - num[cw[i].l-1];
                cw[i].ans -= sum[cw[i].r] - sum[cw[i].l-1];
            }else {
                //printf("*%lld %d ", cw[i].ans, cw[i].k);
                cw[i].ans -= z_query(cw[i].k, Root[cw[i].l-1], Root[cw[i].r], L, R);
                //printf("%lld %d\n", cw[i].ans, T);
                cw[i].k = 0;
            }
            //printf("%d %d %d\n", cw[i].l, cw[i].r, cw[i].k);
        }
        for(int i = 1; i <= n; ++i) if(ar[i]>>T&1) ar[i] >>= 1;
        //printf("***\n");
    }
    for(int i = 1; i <= q; ++i) printf("%lld\n", cw[i].ans);
    return 0;
}

E div1

//E
题解就在这个博客里
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
namespace lh {
#define o2(x) (x)*(x)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long uLL;
    typedef pair<int, LL> pii;
}

using namespace lh;
const int MX = 2e5 + 5;
//const int P = (479 << 21) + 1;
const int P = 998244353;
const int MOD = 998244353;
const int G = 3;
const int NUM = 20;
struct my_NTT {
    LL wn[NUM];
    LL a[MX << 1], b[MX << 1];
    LL pow (LL a, LL x, LL mod) {
        LL ans = 1;
        a %= mod;
        while (x) {
            if (x & 1) ans = ans * a % mod;
            x >>= 1;
            a = a * a % mod;
        }
        return ans;
    }
    //在程序的开头就要放
    void init() {
        for (int i = 0; i < NUM; i++) {
            int t = 1 << i;
            wn[i] = pow (G, (P - 1) / t, P);
        }
    }
    void Rader (LL F[], int len) {
        int j = len >> 1;
        for (int i = 1; i < len - 1; i++) {
            if (i < j) swap (F[i], F[j]);
            int k = len >> 1;
            while (j >= k) j -= k, k >>= 1;
            if (j < k) j += k;
        }
    }
    void NTT (LL F[], int len, int t) {
        Rader (F, len);
        int id = 0;
        for (int h = 2; h <= len; h <<= 1) {
            id++;
            for (int j = 0; j < len; j += h) {
                LL E = 1;
                for (int k = j; k < j + h / 2; k++) {
                    LL u = F[k];
                    LL v = E * F[k + h / 2] % P;
                    F[k] = (u + v) % P;
                    F[k + h / 2] = (u - v + P) % P;
                    E = E * wn[id] % P;
                }
            }
        }
        if (t == -1) {
            for (int i = 1; i < len / 2; i++) swap (F[i], F[len - i]);
            LL inv = pow (len, P - 2, P);
            for (int i = 0; i < len; i++) F[i] = F[i] * inv % P;
        }
    }
    void Conv (LL a[], LL b[], int len) {
        NTT (a, len, 1);
        NTT (b, len, 1);
        for (int i = 0; i < len; i++) a[i] = a[i] * b[i] % P;
        NTT (a, len, -1);
    }
    int gao (LL A[], LL B[], int n, int m, LL ans[]) {//0~n-1
        int len = 1;
        while (len < n + m) len <<= 1;
        for (int i = 0; i < n; i++) a[i] = A[i];
        for (int i = 0; i < m; i++) b[i] = B[i];
        for (int i = n; i < len; i++) a[i] = 0;
        for (int i = m; i < len; i++) b[i] = 0;
        Conv (a, b, len);
        for (int i = 0; i < len; i++) ans[i] = (ans[i]+a[i])%MOD;
        return len;
    }
}ntt;
const int MXN = 2e5 + 5;
int n, m;
int ar[MXN], br[MXN];
LL A[MXN], B[MXN];
std::vector<int> all[MXN], bll[MXN];
LL ans[MXN];
void solve1(int id) {
    for(int i = 0; i < all[id].size(); ++i) {
        for(int j = 0; j < bll[id].size(); ++j) {
            ans[all[id][i]+bll[id][j]] += (LL)all[id][i] * bll[id][j];
            ans[all[id][i]+bll[id][j]] %= MOD;
        }
    }
}
void solve2(int id) {
    for(int i = 0; i <= n+m; ++i) A[i] = B[i] = 0;
    for(int i = 0; i < all[id].size(); ++i) A[all[id][i]] = all[id][i];
    for(int i = 0; i < bll[id].size(); ++i) B[bll[id][i]] = bll[id][i];
    int len = ntt.gao(A, B, all[id].back()+1, bll[id].back()+1, ans);
}
int main(int argc, char const *argv[]) {
    scanf("%d%d", &n, &m); ++n, ++m;
    ntt.init();
    std::vector<int> vs;
    for(int i = 0; i < n; ++i) scanf("%d", &ar[i]), vs.push_back(ar[i]);
    for(int i = 0; i < m; ++i) scanf("%d", &br[i]), vs.push_back(br[i]);
    sort(vs.begin(), vs.end());
    vs.erase(unique(vs.begin(), vs.end()), vs.end());
    for(int i = 0, tmp; i < n; ++i) {
        tmp = lower_bound(vs.begin(), vs.end(), ar[i]) - vs.begin();
        all[tmp].push_back(i);
    }
    for(int i = 0, tmp; i < m; ++i) {
        tmp = lower_bound(vs.begin(), vs.end(), br[i]) - vs.begin();
        bll[tmp].push_back(i);
    }
    for(int i = 0; i < vs.size(); ++i) {
        if(all[i].size() + bll[i].size() <= 10000) solve1(i);
        else solve2(i);
    }
    for(int i = 0; i <= n + m-2; ++i) printf(i!=n+m-2?"%lld ":"%lld\n", ans[i]);
    return 0;
}

day7

G div1&2

//G
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int MXN = 2e2 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m;
int ar[MXN][MXN], pos[MXN][MXN];
int vis[MXN], far[MXN], is[MXN], id[MXN];
int flag;
std::vector<int> mp[MXN];
void dfs(int u,int ba) {
    vis[u] = 1;
    flag ++;
    for(auto v: mp[u]) {
        if(vis[v]) continue;
        dfs(v, u);
    }
}
int main(){
    scanf("%d%d", &n, &m);
    queue<int> Q;
    for(int i = 1, k; i <= m; ++i) {
        scanf("%d", &k);
        ar[i][0] = k;
        for(int j = 1, x; j <= k; ++j) {
            scanf("%d", &ar[i][j]);
            is[ar[i][j]] = 1;
        }
    }
    int cnt = INF;
    for(int i = 1; i <= m; ++i) {
        for(int j = 2; j <= ar[i][0]; ++j) {
            mp[ar[i][j]].push_back(ar[i][j-1]);
        }
    }
    for(int i = 1; i <= n; ++i) {
        flag = 0;
        memset(vis, 0, sizeof(vis));
        dfs(i, i);
        cnt = min(cnt, flag);
    }
    printf("%d\n", cnt);
    return 0;
}

A div1

//A
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;

const int MXN = 2e5 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m;
std::vector<int> mp[MXN];
int is[MXN], dep[MXN],dp[MXN], ans;
void dfs(int u,int ba,int d) {
    int sum = 0;
    if(is[u]) dep[d] ++;
    m = max(m, d);
    for(auto v: mp[u]) {
        if(v == ba) continue;
        dfs(v, u, d + 1);
    }
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &is[i]);
    for(int i = 1, a, b; i < n; ++i) {
        scanf("%d%d", &a, &b);
        mp[a].push_back(b);
        mp[b].push_back(a);
    }
    dfs(1, 1, 0);
    for(int i = 1; i <= 2*n; ++i) {
        //ans += max(dep[i]-1,0);
        if(dep[i] >= 2) {
            dep[i+1] += dep[i]-1;
        }
        if(dep[i]) ans = i;
    }
    printf("%d\n", ans);
    return 0;
}

E div2

//E
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

const int MXN = 2e3 + 6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m;
int ar[MXN], br[MXN], ans[MXN], is[MXN];
int main(){
    scanf("%d", &n);
    std::vector<pii> dai;
    for(int i = 0; i < n; ++i) scanf("%d", &br[i]), dai.push_back({br[i],i});
    memset(ans, -1, sizeof(ans));
    int cnt = 1;
    while(cnt <= n) {
        int MMIN = INF, pos = -1, ers;
        //printf("cnt = %d\n", cnt);
        for(int i = 0; i < dai.size(); ++i) {
            int tmp = dai[i].fi % n;
            while(ans[tmp] != -1) {
                tmp = (tmp + 1) % n;
            }
            //printf("*%d %d %d\n", dai[i].fi, tmp, dai[i].se);
            if(tmp == dai[i].se) {
                if(MMIN > dai[i].fi) {
                    MMIN = dai[i].fi;
                    pos = tmp;
                    ers = i;
                }
            }
        }
        //printf("--%d %d\n", MMIN, pos);
        if(cnt != n) printf("%d ", MMIN);
        else {
            printf("%d\n", MMIN);
            break;
        }
        ans[pos] = MMIN;
        for(int i = ers; i < dai.size() - 1; ++i) {
            dai[i] = dai[i+1];
        }
        dai.resize(dai.size()-1);
        cnt ++;
    }
    return 0;
}

C div1

//C
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

const int MXN = 2e5 + 6;
const int INF = 0x3f3f3f3f;
const LL mod = 998244353;
LL n, m;
typedef vector<long long> vec;
typedef vector<vec > mat;

mat Mul(mat a, mat b) {
    mat c(a.size(), vec(b[0].size()));
    for(int k = 0; k < b.size(); ++k) {
        for(int i = 0; i < a.size(); ++i) {
            if(a[i][k] == 0) continue;
            for(int j = 0; j < b[0].size(); ++j) {
                c[i][j] = (c[i][j] + a[i][k] * b[k][j])%mod;
            }
        }
    }
    return c;
}
mat mat_ksm(mat a, LL b) {
    mat res(a.size(), vec(a.size()));
    for(int i = 0; i < a.size(); ++i) res[i][i] = 1;
    while(b) {
        if(b&1) res = Mul(res, a);
        a = Mul(a, a);
        b >>= 1;
    }
    return res;
}
LL fib_n(LL n) {
    mat a(2, vec(2));
    a[0][0] = 1; a[0][1] = 1;
    a[1][0] = 1; a[1][1] = 0;
    a = mat_ksm(a, n);
    return a[1][0];
}
LL getnum(LL n) {
    LL ans = n - n/3, now = 2;
    n /= 3;
    while(n) {
        ans = (ans + (n+1)/2*now%mod)%mod;
        n /= 2;
        if(now == 2) now = 8;
        else now = now*2%mod;
    }
    return ans;
}
int main(){
    int tim; scanf("%d", &tim);
    while(tim --) {
        scanf("%lld", &n);
        if(n <= 2) {
            printf("0\n");
            continue;
        }
        LL ans = (fib_n(n+2) - 1 + mod)%mod;
        printf("%lld\n", (ans - getnum(n) + mod)%mod);
    }
    return 0;
}

F div2

//F
//假设a > b且a^b的最高位是第i位, 则a^s > b^s的条件是s的第i位为0.
#include<bits/stdc++.h>
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

const int MXN = 1e5 + 6;
const int INF = 0x3f3f3f3f;
const LL mod = 998244353;

int n, m;
LL ar[MXN];
LL dp[55][2][55][2];
LL two[55], my[55][2], num[55];
std::vector<int> vs;
int solve(int tn) {
    while(tn) {
        vs.push_back(tn&1);
        tn >>= 1;
    }
    int cnt = 1;
    LL T = 1;
    for(auto x: vs) {
        num[cnt] = num[cnt-1]+T*x;
        ++ cnt; T *= 2;
    }
    reverse(vs.begin(), vs.end());
    LL zhi = vs[0];
    int len = vs.size();
    my[1][0] = (two[len-1] - 1 + mod) % mod;
    my[1][1] = m - (1LL<<(len-1)) + 1;
    assert(my[1][0]+my[1][1] == m);
    for(int i = 1; i < len; ++i) {
        if(vs[i]) {
            my[i+1][1] = num[len-i-1] + 1 + (zhi)*two[len-i-1];
            my[i+1][0] = (zhi+1)*two[len-i-1] - 1;
        }else {
            my[i+1][1] = (zhi)*two[len-i-1];
            my[i+1][0] = num[len-i-1] + 1 + (zhi)*two[len-i-1] - 1;
        }
        my[i+1][1] = (my[i+1][1]%mod + mod)%mod;
        my[i+1][0] = (my[i+1][0]%mod + mod)%mod;
        assert(my[i][0]+my[i][1] == m);
        zhi = zhi * 2 + vs[i];
    }
    return len;
}
int get(LL NUM) {
    int x = 0;
    while(NUM) {
        ++ x;
        NUM /= 2;
    }
    return x;
}
int main(){
    scanf("%d%d", &n, &m);
    two[0] = 1; for(int i = 1; i <= 32; ++i) two[i] = two[i-1] * 2 % mod;
    int len = solve(m);
    for(int i = 1; i <= n; ++i) scanf("%lld", &ar[i]);
    if(n == 1) {printf("0\n");return 0;}
    LL ANS = 0, temp;
    for(int i = 1; i < n; ++i) {
        for(int j = i + 1; j <= n; ++j) {
            int tmp = get(ar[i]^ar[j]); temp = 0;
            if(ar[i] > ar[j]) {
                if(tmp > len) temp = m;
                else temp = my[len-tmp+1][0];
            }else {
                if(tmp <= len) temp = my[len-tmp+1][1];
            }
            ANS = (ANS + temp + mod)%mod;
        }
    }
    printf("%lld\n", ANS%mod);
    return 0;
}
这个题也可以跑数位dp,比如这样:
LL solve(int id, int ip, int pos, int pre, bool zero, bool limit) {//第id位必须为ip的方案数
    if(pos == -1) {
        if(zero) return 0;
        return 1;
    }
    if(!limit&&!zero&&dp[id][ip][pos][pre]!=-1) return dp[id][ip][pos][pre];
    int up = limit?num[pos]:1, low = 0;
    LL sum = 0;
    if(pos == id) {
        if(limit && num[pos] == 0 && ip == 1) return 0;
        up = low = ip;
    }
    for(int i = low; i <= up; ++i) {
        sum += solve(id, ip, pos-1, i, zero&&i==0,limit&&i==num[pos]);
    }
    if(!limit&&!zero) dp[id][ip][pos][pre] = sum;
    return sum;
}

day8

G div1&2

//div1G
题解:https://blog.csdn.net/qq_39599067/article/details/86713379
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MXN = 2e3 + 7;
const LL mod = 998244353;
int n, m;
int ar[MXN][MXN];
LL sum[MXN][MXN], sum1[MXN][MXN], sum2[MXN][MXN], sum3[MXN][MXN],sum4[MXN][MXN];
LL up[MXN][MXN], Left[MXN][MXN], Right[MXN][MXN], down[MXN][MXN];
char s[MXN];
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) {
        scanf("%s", s+1);
        for(int j = 1; j <= m; ++j) ar[i][j] = s[j] - '0';
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 1, tmp; j <= m; ++j) {
            if(ar[i][j] == 0) tmp = 0;else tmp = i*j;
            sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+tmp;
            sum[i][j] = (sum[i][j]%mod+mod)%mod;
        }
    }
    for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) sum1[i][j] = sum[i-1][j-1];
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i <= n; ++i) {
        for(int j = m, tmp; j >= 1; --j) {
            if(ar[i][j] == 0) tmp = 0;else tmp = i*(m-j+1);
            sum[i][j] = sum[i-1][j]+sum[i][j+1]-sum[i-1][j+1]+tmp;
            sum[i][j] = (sum[i][j]%mod+mod)%mod;
        }
    }
    for(int i = 1; i <= n; ++i) for(int j = m; j >= 1; --j) sum2[i][j] = sum[i-1][j+1];
    memset(sum, 0, sizeof(sum));
    for(int i = n; i >= 1; --i) {
        for(int j = 1, tmp; j <= m; ++j) {
            if(ar[i][j] == 0) tmp = 0;else tmp = (n-i+1)*j;
            sum[i][j] = sum[i+1][j]+sum[i][j-1]-sum[i+1][j-1]+tmp;
            sum[i][j] = (sum[i][j]%mod+mod)%mod;
        }
    }
    for(int i = n; i >= 1; --i) for(int j = 1; j <= m; ++j) sum3[i][j] = sum[i+1][j-1];
    memset(sum, 0, sizeof(sum));
    for(int i = n; i >= 1; --i) {
        for(int j = m, tmp; j >= 1; --j) {
            if(ar[i][j] == 0) tmp = 0;else tmp = (n-i+1)*(m-j+1);
            sum[i][j] = sum[i+1][j]+sum[i][j+1]-sum[i+1][j+1]+tmp;
            sum[i][j] = (sum[i][j]%mod+mod)%mod;
        }
    }
    for(int i = n; i >= 1; --i) for(int j = m; j >= 1; --j) sum4[i][j] = sum[i+1][j+1];

    for(int i = 2; i <= n; ++i) {
        for(int j = 1, tmp; j <= m; ++j) {
            if(ar[i-1][j] == 0) tmp = 0; else tmp = (i-1)*j;
            up[i][j] = up[i-1][j] + tmp;
            up[i][j] %= mod;
        }
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 2, tmp; j <= m; ++j) {
            if(ar[i][j-1] == 0) tmp = 0; else tmp = i*(j-1);
            Left[i][j] = Left[i][j-1] + tmp;
            Left[i][j] %= mod;
        }
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = m - 1, tmp; j >= 1; --j) {
            if(ar[i][j+1] == 0) tmp = 0; else tmp = (n-i+1)*(m-j);
            Right[i][j] = Right[i][j+1] + tmp;
            Right[i][j] %= mod;
        }
    }
    for(int i = n-1; i >= 1; --i) {
        for(int j = 1, tmp; j <= m; ++j) {
            if(ar[i+1][j] == 0) tmp = 0; else tmp = (n-i)*(m-j+1);
            down[i][j] = down[i+1][j] + tmp;
            down[i][j] %= mod;
        }
    }
    LL ans = 0;
    for(LL i = 1; i <= n; ++i) {
        for(LL j = 1; j <= m; ++j) {
            if(ar[i][j] == 0) continue;
            ans = (ans + i*j%mod*(n-i+1)%mod*(m-j+1)%mod) % mod;
            ans = (ans + (sum1[i][j]+up[i][j]+Left[i][j])%mod*(n-i+1)%mod*(m-j+1)%mod)%mod;
            ans = (ans + (Right[i][j]+down[i][j]+sum4[i][j])%mod*i%mod*j%mod)%mod;
            ans = (ans + sum2[i][j]*(n-i+1)%mod*j%mod+sum3[i][j]*(m-j+1)%mod*i%mod)%mod;
        }
    }
    printf("%lld\n", (ans+mod)%mod);
    return 0;
}
//div2G
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

const int INF = 0x3f3f3f3f;
const int MXN = 1e6 + 6;
const LL mod = 998244353;
LL san[33];
LL dp[44][44][3][44];
int ar[2005][2005];
char s[2005];
LL o2(LL x, LL y) {
    return (x*(x+1)/2)*(y*(y+1)/2)%mod;
}
int main() {
    LL n, m;
    scanf("%lld%lld", &n, &m);
    LL ans = 0;
    for(LL i = 1; i <= n; ++i) {
        scanf("%s", s+1);
        for(LL j = 1; j <= m; ++j) {
            int x = s[j]-'0';
            if(x == 0) continue;
            ans += o2(n,m) - o2((i-1),m) - o2((n-i),m) - o2((j-1),n) - o2((m-j),n);
            ans += o2((i-1),(j-1))+o2((i-1),(m-j))+o2((n-i),(j-1))+o2((n-i),(m-j));
            ans = (ans % mod + mod) % mod;
        }
    }
    printf("%lld\n", ans);
    return 0;
}

D div2

//D
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MXN = 4e1 + 7;
const LL mod = 998244353;
int n, m;
LL dp[MXN][MXN][MXN][3];
int main() {
    scanf("%d", &n); n <<= 1;
    dp[1][1][0][1] = 1;
    dp[1][0][1][2] = 1;
    dp[2][1][1][0] = 1;
    for(int i = 1; i <= n; ++i) {
        for(int x = 0; x <= i; ++x) {
            for(int y = 0; y + x <= i; ++y) {
                dp[i+2][x+1][y+1][0] = (dp[i][x][y][1] + dp[i][x][y][2])%mod;
                dp[i+1][x+1][y][1] = (dp[i][x][y][1] + dp[i][x][y][0])%mod;
                dp[i+1][x][y+1][2] = (dp[i][x][y][2] + dp[i][x][y][0])%mod;
            }
        }
    }
    LL ans = (dp[n][n/2][n/2][0]+dp[n][n/2][n/2][1]+dp[n][n/2][n/2][2]) % mod;
    printf("%lld\n", ans);
    return 0;
}
/*
id = 0表示空白
id = 1表示左
id = 2表示右
dp[i][x][y][id]到第i天选了x个左y个右最后一个是id的方案数
人人为我:
dp[i][x][y][0] = dp[i-2][x-1][y-1][1] + dp[i-2][x-1][y-1][2];
dp[i][x][y][1] = dp[i-1][x-1][y][1] + dp[i-1][x-1][y][2] + dp[i-1][x-1][y][0];
dp[i][x][y][2] = dp[i-1][x][y-1][2] + dp[i-1][x][y-1][0];
我为人人:
dp[i+2][x+1][y+1][0] = dp[i][x][y][1] + dp[i][x][y][2];
dp[i+1][x+1][y][1] = dp[i][x][y][1] + dp[i][x][y][2] + dp[i][x][y][0];
dp[i+1][x][y+1][2] = dp[i][x][y][2] + dp[i][x][y][0];
*/

A div1

//A
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MX = 4e6 + 7;
int n;
vector<int> cw[MX];
vector<int> vs;
int vis[MX];
int mp[MX];

int D, ANS;
inline int upup(int u, int d) {
    if(vis[u]) {ANS = d + vis[u];return vis[u];}
    vis[u] = d;
    int T = upup(mp[u], d+1);
    vis[u] = min(vis[u], T + 1);
    return vis[u];
}
int main() {
    scanf("%d", &n);
    if(n == 1) {
        printf("1 -1\n");
        return 0;
    }
    for(int i = 2, u; i <= n; ++i) {
        scanf("%d", &u);
        cw[u].push_back(i);
        mp[i] = u;
    }
    for(int i = 1;i <= n;i++) if(cw[i].size() == 0) vs.push_back(i);
    sort(vs.begin(), vs.end());
    printf("%d -1\n", vs[0]);
    vis[0] = 1e8;
    upup(vs[0], 0);
    for(int i = 1; i < vs.size(); ++i) {
        upup(vs[i], 0);
        printf("%d %d\n", vs[i], ANS);
        //io.wint(vs[i],0);io.wint(len+D,1);
    }
    return 0;
}
//写的sb代码
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MX = 4e6 + 7;
int n;
LL sum[MX<<2];
int lazy[MX<<2];
vector<int> cw[MX];
vector<int> vs;
int vis[MX];
int mp[MX];
int inde;
int sz[MX],top[MX],son[MX],dep[MX],faz[MX];
int tid[MX];


inline void push_up(int rt) {
    sum[rt] = sum[lson] + sum[rson];
}
inline void push_down(int l,int mid, int r,int rt) {
    if(lazy[rt]) {
        int c = lazy[rt];
        lazy[lson]+=c;
        lazy[rson]+=c;
        sum[lson]+=(LL)c*(mid-l+1);
        sum[rson]+=(LL)c*(r-mid);
        lazy[rt] = 0;
    }
}
void update(int L,int R,int c,int rt,int l,int r) {
    int mid=(l+r)>>1;
    if(l>R||r<L)return;
    if(L<=l&&r<=R) {
        lazy[rt] += c;
        sum[rt] += (LL)c*(r-l+1);
        return;
    }
    if(l == r) return;
    push_down(l,mid,r,rt);
    if(L > mid) update(L, R, c, rson, mid+1, r);
    else if(R <= mid) update(L,R,c,lson,l,mid);
    else {
        update(L,mid,c,lson,l,mid);
        update(mid+1,R,c,rson,mid+1,r);
    }
    push_up(rt);
}
LL query(int L,int R,int rt,int l,int r) {
    int mid=(l+r)>>1;
    if(L<=l&&r<=R) {
        return sum[rt];
    }
    if(l>R||r<L)return 0;
    if(l==r)return 0;
    push_down(l,mid,r,rt);
    if(L > mid)return query(L, R, rson, mid+1, r);
    else if(R <= mid)return query(L,R,lson,l,mid);
    else {
        return query(L,mid,lson,l,mid)+
        query(mid+1,R,rson,mid+1,r);
    }
}
void dfs1(int u,int fat,int depth) {
    dep[u] = depth;
    faz[u] = fat;
    sz[u] = 1;
    son[u] = 0;
    int len = cw[u].size();
    if(len == 0) vs.push_back(u);
    for(int i=0; i < len; ++i) {
        int v = cw[u][i];
        dfs1(v,u,depth+1);
        sz[u] += sz[v];
        if(sz[v]>sz[son[u]]) {
            son[u] = v;
        }
    }
}
void dfs2(int u,int t) {
    tid[u] = ++inde;
    if(son[u]) {
        top[son[u]] = top[u];
        dfs2(son[u],u);
    }
    int len = cw[u].size();
    for(int i=0; i < len; ++i) {
        int v = cw[u][i];
        if(v!=son[u]&&v!=faz[u]) {
            top[v]=v;
            dfs2(v,u);
        }
    }
}
LL path_query(int x,int y) {
    LL ans=0;
    int fx=top[x],fy=top[y];
    while(fx!=fy) {
        if(dep[fx]>=dep[fy]) {
            ans=(ans+query(tid[fx],tid[x],1,1,n+2));
            x=faz[fx];
        } else {
            ans=(ans+query(tid[fy],tid[y],1,1,n+2));
            y=faz[fy];
        }
        fx=top[x],fy=top[y];
    }
    if(tid[x]<tid[y]) {
        ans=(ans+query(tid[x],tid[y],1,1,n+2));
    } else {
        ans=(ans+query(tid[y],tid[x],1,1,n+2));
    }
    return ans;
}
void path_update(int x,int y,int c) {
    int fx=top[x],fy=top[y];
    while(fx!=fy) {
        if(dep[fx]>dep[fy]) {
            update(tid[fx],tid[x],c,1,1,n+2);
            x=faz[fx];
        } else {
            update(tid[fy],tid[y],c,1,1,n+2);
            y=faz[fy];
        }
        fx=top[x],fy=top[y];
    }
    if(tid[x]<tid[y]) {
        update(tid[x],tid[y],c,1,1,n+2);
    } else {
        update(tid[y],tid[x],c,1,1,n+2);
    }
}
void pre_build() {
    int root = 1;
    
    top[root]=root;
    dfs2(root,root);
}
int D;
inline int upup(int u, int d) {
    if(vis[u]) {vis[u] = min(vis[u], d+1);D = d+1;return u;}
    vis[u] = d;
    //if(d) path_update(u, u, d);
    return upup(mp[u], d+1);
}
int main() {
    scanf("%d", &n);
    //n = io.xint();
    if(n == 1) {
        //io.wint(1,0);io.wint(-1,1);
        printf("1 -1\n");
        return 0;
    }
    for(int i = 2, u; i <= n; ++i) {
        //u = io.xint();
        scanf("%d", &u);
        cw[u].push_back(i);
        mp[i] = u;
    }
    int root = 1;
    //dfs1(root,root,1);
    //pre_build();
    for(int i = 1;i <= n;i++) if(cw[i].size() == 0) vs.push_back(i);
    sort(vs.begin(), vs.end());
    printf("%d -1\n", vs[0]);
    //io.wint(vs[0],0);io.wint(-1,1);
    upup(vs[0], 0);
    for(int i = 1; i < vs.size(); ++i) {
        int tmp = upup(vs[i], 0);
        printf("%d %d\n", vs[i], vis[tmp] + D);
        //io.wint(vs[i],0);io.wint(len+D,1);
    }
    return 0;
}

B div1

#include<bits/stdc++.h>
#define clr(a, b) memset(a,b,sizeof((a)))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MXN = 2e4 + 7;
const LL mod = 998244353;
int n, m;
struct lp {
    int u, v;
}cw[MXN];
std::vector<int> son[MXN];
int vis[MXN], be[MXN], is[MXN];
int L;
bool dfs(int u){
    for(auto x : son[u]){
        if(x < L) continue;
        if(vis[x]) continue;
        vis[x] = 1;
        if(is[x] == -1 || dfs(is[x])){
            is[x] = u;
            be[u] = x;
            return true;
        }
    }
    return false;
}
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 0; i < m; ++i) {
        scanf("%d%d", &cw[i].u, &cw[i].v);
        cw[i].u++; cw[i].v++;
        if(cw[i].u > cw[i].v) swap(cw[i].u, cw[i].v);
        son[cw[i].u].push_back(cw[i].v);
    }
    for(int i = 1; i <= n; ++i) is[i] = be[i] = -1;
    int ans = 1;
    for(int i = 1; i <= n; ++i) {
        L = i + 1;
        if(is[i] != -1) {
            for(int j = 1; j <= n; ++j) vis[j] = 0;
            if(!dfs(is[i])) break;
            is[i] = -1;
        }
        for(int j = 1; j <= n; ++j) vis[j] = 0;
        if(dfs(i)) ++ ans;
        else break;
    }
    printf("%d\n", ans - 1);
    return 0;
}
/*
考虑二分答案是否>= x,可以把图变成一个二分图,左边是< x的,右边是>= x的。在原图中两部分
内部是可能有边的,但是选出这些边不会对“答案能达到x”更有利,所以这些边忽略即可。然后可以用匈
牙利算法检查是否左边的点是否全部都能匹配上。时间复杂度O(nmlogn),因为匈牙利算法很难卡到上
限O(nm)且常数很小,所以也能通过。 
实际上二分答案的过程可以去掉。我们考虑把二分的过程变成从小到大枚举,到x + 1的时候就是把x点
加入二分图的左边。如果x之前在右边的时候和某个左边的点v匹配过了,把这个匹配关系拆掉,把v再
匹配一遍就可以了。时间复杂度O(nm)。 
如果用Dinic或者HK的话,时间复杂度可以做到O(m√n)。
*/

E div2

//vector被卡常数了,死活过不去卧槽
//div2就是一个矩阵乘法,div1要用线段树优化一下
//不过说实话,这个n*m*9的复杂度能过这一题,我也是醉了
#include<bits/stdc++.h>
#define clr(a, b) memset(a,b,sizeof((a)))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MXN = 1e4 + 7;
const LL mod = 998244353;
int n, m;
LL sum[2][3];
int ar[MXN][3][3], tmp[3][3];
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i < n; ++i) {
        for(int j = 0; j < 3; ++j) {
            for(int k = 0; k < 3; ++k) {
                scanf("%d", &ar[i][j][k]);
            }
        }
    }
    int opt, l, r;
    while(m --) {
        scanf("%d%d%d", &opt, &l, &r);
        if(opt == 1) {
            for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) scanf("%d", &tmp[i][j]);
            for(int i = l; i <= r; ++i) for(int j = 0; j < 3; ++j) for(int k = 0; k < 3; ++k) {
                ar[i][j][k] = tmp[j][k];
            }
        }else {
            opt = 1;
            sum[0][0] = sum[0][1] = sum[0][2] = 1;
            for(int i = l; i < r; ++i) {
                for(int j = 0; j < 3; ++j) sum[opt][j] = 0;
                for(int k = 0; k < 3; ++k) {
                    for(int j = 0; j < 3; ++j) {
                        sum[opt][j] = (sum[opt][j]+sum[opt^1][k]*ar[i][k][j])%mod;
                    }
                }
                opt ^= 1;
            }
            printf("%lld\n", (sum[opt^1][0]+sum[opt^1][1]+sum[opt^1][2])%mod);
        }
    }
    return 0;
}

E div1

//哇,这题ac完感觉好爽啊
//第一次写这种结构体线段树还重载操作符的,舒服
//没有人写博客,只能看着官方题解意会解法
#include<bits/stdc++.h>
#define clr(a, b) memset(a,b,sizeof((a)))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;

const int MXN = 2e5 + 7;
const LL mod = 998244353;

int n, m, Q;
int ar[MXN][3][3], two[33];
int lazy[MXN<<2][3][3], flag[MXN<<2];
map<int, int> mp;

struct edge {
    int opt, l, r;
    int ar[3][3];
}node[MXN];
struct lp {
    int sum[3][3];
    friend lp operator *(const lp&a, const lp&b) {
        lp c;
        clr(c.sum, 0);
        for(int k = 0; k < 3; ++k) for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) {
            c.sum[i][j] = (c.sum[i][j]+(LL)a.sum[i][k]*b.sum[k][j])%mod;
        }
        return c;
    }
}cw[MXN<<2], tp[MXN][33];

void push_up(int rt) {
    cw[rt] = cw[lson] * cw[rson];
}
void build(int l,int r,int rt) {
    flag[rt] = -1;
    if(l == r) {
        for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) cw[rt].sum[i][j] = ar[l][i][j];
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, lson); build(mid+1,r,rson);
    push_up(rt);
}
void push_down(int l,int mid,int r,int rt) {
    if(flag[rt] == -1) return;
    flag[lson] = flag[rson] = flag[rt];
    for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) lazy[lson][i][j] = lazy[rt][i][j], lazy[rson][i][j] = lazy[rt][i][j];
    cw[lson] = tp[flag[rt]][mp[mid-l+1]-1];
    cw[rson] = tp[flag[rt]][mp[r-mid]-1];
    assert(mp[mid-l+1]); assert(mp[r-mid]);
    flag[rt] = -1;
}
void update(int L,int R,int id,int l,int r,int rt) {
    if(L <= l && r <= R) {
        flag[rt] = id;
        for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) lazy[rt][i][j] = node[id].ar[i][j];
        assert(mp[r-l+1]);
        cw[rt] = tp[id][mp[r-l+1]-1];
        return ;
    }
    int mid = (l + r) >> 1;
    push_down(l, mid, r, rt);
    if(L > mid) update(L, R, id, mid+1, r, rson);
    else if(R <= mid) update(L, R, id, l, mid, lson);
    else {
        update(L,mid,id,l,mid,lson); update(mid+1,R,id,mid+1,r,rson);
    }
    push_up(rt);
}
lp query(int L,int R,int l,int r,int rt) {
    if(L <= l && r <= R) {
        return cw[rt];
    }
    int mid = (l + r) >> 1;
    push_down(l, mid, r, rt);
    if(L > mid) return query(L, R, mid+1, r, rson);
    else if(R <= mid) return query(L, R, l, mid, lson);
    else {
        return query(L,mid,l,mid,lson)*query(mid+1,R,mid+1,r,rson);
    }
}
int main() {
    two[0] = 1, mp[1] = 1;
    for(int i = 1; i <= 17; ++i) two[i] = two[i-1] << 1, mp[1<<i] = i + 1;
    //printf("%d %d\n", two[17], mp[1<<17]-1);
    scanf("%d%d", &n, &Q);
    for(int i = 1; i < n; ++i) {
        for(int j = 0; j < 3; ++j) for(int k = 0; k < 3; ++k) scanf("%d", &ar[i][j][k]);
    }
    m = 2;
    while(m < n) m <<= 1;
    build(1, m, 1);
    int opt, l, r;
    for(int i = 1; i <= Q; ++i) {
        scanf("%d%d%d", &node[i].opt, &node[i].l, &node[i].r);
        if(node[i].opt == 1) {
            for(int k = 0; k < 3; ++k) for(int j = 0; j < 3; ++j) {
                scanf("%d", &node[i].ar[k][j]);
                tp[i][0].sum[k][j] = node[i].ar[k][j];
            }
            for(int k = 1; k <= 17; ++k) {
                tp[i][k] = tp[i][k-1] * tp[i][k-1];
            }
            /*printf("***\n");
            for(int h = 0; h < 3; ++ h) {
                for(int k = 0; k < 3; ++k) {
                    for(int j = 0; j < 3; ++j) {
                        printf("%d ", tp[i][h].sum[k][j]);
                    }
                    printf("\n");
                }
            }*/
            update(node[i].l, node[i].r, i, 1, m, 1);
        }else {
            LL ans = 0;
            lp a = query(node[i].l, node[i].r-1, 1, m, 1);
            for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) ans = (ans + a.sum[i][j]) % mod;
            printf("%lld\n", ans);
        }
    }
    return 0;
}

I div1

//题解 https://blog.csdn.net/qq_39599067/article/details/86747863
#include<bits/stdc++.h>
#define clr(a, b) memset(a,b,sizeof((a)))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;

const int MXN = 3e5 + 7;
const int MOD = 998244353;
int n, m, Q;
int LN;
LL ar[1<<21], br[MXN], inv2;
LL ksm(LL a, int b) {
    LL res = 1;
    for(; b; b>>=1, a=a*a%MOD) {
        if(b&1) res = res * a % MOD;
    }
    return res;
}
void FWT_xor(LL *a,int LN,int opt) {
    for(int i=1;i<LN;i<<=1)
        for(int p=i<<1,j=0;j<LN;j+=p)
            for(int k=0;k<i;++k) {
                LL X=a[j+k],Y=a[i+j+k];
                a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD;
                if(opt==-1)a[j+k]=a[j+k]*inv2%MOD,a[i+j+k]=a[i+j+k]*inv2%MOD;
            }
}
int main() {
    inv2 = ksm(2, MOD - 2);
    scanf("%d", &n);
    for(int i = 0, tmp; i < n; ++i) {
        tmp = 0;
        for(int j = 0, x; j < 10; ++j) {
            scanf("%d", &x);
            if(x == 0) tmp <<= 2;
            else if(x == 1) tmp <<= 2, tmp |= 1;
            else tmp <<= 1, tmp |= 1, tmp <<= 1;
        }
        ++ ar[tmp];
    }
    LN = (1<<20);
    FWT_xor(ar, LN, 1);
    for (int i = 0; i < LN; ++i) ar[i] = ar[i] * ar[i] % MOD;
    FWT_xor(ar, LN, -1);
    //ar[x] 表示有多少对ai和aj异或结果为x
    LL ans = 0;
    for(int i = 0, tmp, cnt; i < LN; ++i) {
        tmp = i; cnt = 0;
        for(int j = 0, x; j < 10; ++j) {
            x = tmp & 3;
            if(x == 3) x = 1;
            if(x == 2) x = 4;
            cnt += x;
            tmp >>= 2;
        }
        br[cnt] = (br[cnt] + ar[i]) % MOD;
    }
    for(int i = 0; i <= 40; ++i) {
        ans = (ans + br[i]*br[i]%MOD)%MOD;
    }
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Cwolf9/p/10348914.html
今日推荐