2018.7.20日记&总结

今天又只过了一题,很差!!!
E题应该能想出来的,构造题多找性质,发现很强的性质后构造就很方面了。
看题要有舍有得,有些题显然很难就没必要看了。把注意力放在有人做的可做题上,静下心来深入思考很重要。
如果没有别的题可做,1道题想一小时很正常。多想别的做法,甚至乱搞,但是肯定不能过的做法别多纠结。胆大尝试做法,但过不了果断放弃,不要浪费太多时间。
大胆利用性质猜结论!
调题应该更快,敢于问。注意细节错误!静下心来用眼读代码,边读边思考,减少对拍,因为考场上没法也没时间对拍!!!

题解:
A:求多项式的商。巧妙推式子。
主要是推式子很巧,很好写!

#include<bits/stdc++.h>
using namespace std;
#define maxn 5020
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)

typedef long long ll;
const ll mod = 1e9 + 7;
ll a[maxn],b[maxn],c[maxn],ans,mx;
int m;

inline ll power(ll x,ll y){
    ll res = 1;
    while ( y ){
        if ( y & 1 ) res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return (res + mod) % mod;
}
void cal_C(){
    rep(i,1,m){
        ll mul = 1,x = 1,cur = 0;
        rep(j,1,m) if ( j != i ) mul = mul * (a[j] - a[i]) % mod;
        mul = power(mul,mod - 2);
        rep(j,0,m - 2) cur = (cur + x * b[j]) % mod , x = x * (-a[i]) % mod;
        c[i] = (cur * mul % mod + mod) % mod;
    }
    //rep(i,1,m) c[i] = (c[i] + c[i - 1]) % mod;
}
void solve(){
    rep(i,1,mx){
        ll cur = 0;
        rep(j,1,m){
            if ( a[j] < i ) cur = (cur + c[j]) % mod;
        }
        ans = (ans + cur * power(i,mod - 2)) % mod;
    }
    ans = (ans % mod + mod) % mod;
    printf("%lld\n",ans);
}
int main(){
    freopen("input.txt","r",stdin);
    while ( ~scanf("%d",&m) ){
        mx = ans = 0;
        rep(i,1,m) scanf("%lld",&a[i]) , mx = max(mx,a[i]);
        rep(i,0,m - 2) scanf("%lld",&b[i]);
        cal_C();
        solve();
    }
    return 0;
}

B:巧妙的贪心,利用每个联通块必选一个点,其余点从小到大选。大胆推性质,想结论!

C:N*N矩阵,每行每列填一个数,使两两连线不同。
用原根构造(g^(1 - n-1)恰好为1- p-1).因为保证n +1为质数,所以大胆猜想与原根有关。
填(i,g^i % (n + 1))

D:求对于每个前缀i,找一个分界点j,xorsum(1,j) + xorsum(j +1,i)最大。
每一位,出现奇数次为0(因为无论怎么选都贡献1),偶数次为1(想选到奇数次分开,就贡献2)
相当于查询x在pre中&的最大值。
F[1<<10][1<<10]的分块过不了
考虑直接对一个pre的所有子集进行更新,查询时只需知道当前要填的数是否被包含,就可以唯一确定,非常巧妙!
O(nlogn)
注意输出优化要特判负数和0

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define maxn (1 << 22)
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define inf 1e8

int a[maxn],ans[maxn],n;
int q[maxn],hh,tt,dfstime,vis[maxn];


inline int read(){
    register int num = 0;
    register char ch = getchar();
    while ( ch > '9' || ch < '0' ) ch = getchar();
    while ( ch <= '9' && ch >= '0' ) num = num * 10 + ch - '0' , ch = getchar();
    return num;
}
int num[10];
inline void write(int x){
    register int cnt = 0;
    if ( !x ){ printf("0"); return; }
    while ( x ) num[++cnt] = x % 10 , x /= 10;
    while ( cnt ) putchar(num[cnt--] + '0');
}
inline void insert(int x){
    if ( vis[x] == dfstime ) return;
    tt = hh = 0; q[tt++] = x , vis[x] = dfstime;
    while ( hh < tt ){
        int x = q[hh++];
        if ( !x ) continue;
        rep(i,0,19){
            if ( (x >> i) & 1 ){
                if ( vis[x ^ (1 << i)] != dfstime ){
                    vis[x ^ (1 << i)] = dfstime;
                    q[tt++] = x ^ (1 << i);
                }
            }
        }
    }
}
inline int query(int x){
    int cur = 0;
    repd(i,19,0){
        if ( x & (1 << i) ){
            if ( vis[cur | (1 << i)] == dfstime ) cur |= 1 << i;
        }
    }
    return cur;
}
int main(){
    freopen("input.txt","r",stdin);
//  freopen("1.out","w",stdout);
    while ( ~scanf("%d",&n) ){
        ++dfstime;
        int pre = 0,cur = 0,S = (1 << 20) - 1;
        rep(i,1,n){
            a[i] = read() , pre ^= a[i] , cur = pre ^ S;
            insert(pre);
            ans[i] = query(cur) * 2 + pre;
        }
        rep(i,1,n){
            write(ans[i]);
        //  if ( i < n ) putchar(' ');  
        //  else putchar(10);
            if ( i < n ) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

E:给出后缀排序后第i位的位置,构造一个0,1的可行解。
每次找到最后一个位置的排名,如果在第一则填0删去,不影响其他点排名。如果不在第一位则必须填1。并且它之前全部为0,之后全部为1。再一次后缀数组判断是否可行。
注意后缀数组有些地方要倒着for(位置靠后字典序更小)
还要一种很巧的判定方法。
rk[sa[i] +1] > rk[sa[i +1] +1]则所需字符集+1,使用于字符集更大的情况

#include<bits/stdc++.h>
using namespace std;
#define maxn 100020
#define rep(i,l,r) for (register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)

int a[maxn];
int s[maxn],c[maxn],t1[maxn * 2],t2[maxn * 2],sa[maxn];
int n;


//sa[i]表示排名为i的后缀的位置
    //rk[i]表示第i个后缀的排名
    //x[i]表示i的排名(第一关键字)
    //y[i]表示第二关键字排名为i的后缀的起始位置
    //h[i]表示后缀i在排序后与前一位的lcp
    //求i,j的lcp是排序后rk[i],rk[j],height的min

void suffix_array(){
    int m = 1 , *x = t1 , *y = t2;
    rep(i,0,m) c[i] = 0;
    rep(i,0,n - 1) c[x[i] = s[i]]++;
    rep(i,1,m) c[i] += c[i - 1];
    rep(i,0,n - 1) sa[--c[x[i]]] = i;
//  rep(i,1,n) cout<<sa[i - 1]<<" ";
//  cout<<endl;;    
    for (register int k = 1 ; k < n ; k <<= 1){
        register int p = 0;
        memset(y,0,sizeof(t1));
        repd(i,n - 1,n - k) y[p++] = i; //必须倒着for,在后面的位置更小
        rep(i,0,n - 1) if ( sa[i] >= k ) y[p++] = sa[i] - k;

        rep(i,0,m) c[i] = 0;
        rep(i,0,n - 1) c[x[y[i]]]++;
        rep(i,1,m) c[i] += c[i - 1];
        repd(i,n - 1,0) sa[--c[x[y[i]]]] = y[i];

        p = 0 , swap(x,y) , x[sa[0]] = ++p;
        rep(i,1,n - 1) x[sa[i]] = (y[sa[i]] == y[sa[i - 1]]) && (y[sa[i] + k] == y[sa[i - 1] + k]) ? p : ++p;
        if ( p >= n ) break; //如果当前已经完成排名,则break
        m = p;
    }
}

bool check(){
//  rep(i,1,n) cout<<sa[i - 1]<<" ";
//  cout<<endl;;
    rep(i,1,n) if ( a[i] != sa[i - 1] + 1 ) return 0;
    return 1;
}
int main(){
    freopen("input.txt","r",stdin);
    while ( ~scanf("%d",&n) ){
        rep(i,1,n) scanf("%d",&a[i]);
        int id = 1;
        while ( a[id] == n - id + 1 ) id++;
        if ( id >= n ){ printf("YES\n"); continue; }
        rep(i,id,n) if ( a[i] == n - id + 1){ id = i; break; }
        rep(i,1,id - 1) s[a[i] - 1] = 0;
        rep(i,id,n) s[a[i] - 1] = 1;
        suffix_array();
        if ( check() ) printf("YES\n");
        else printf("NO\n");        
    }
    return 0;
}

F:特技分块,好题

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define maxn 200020
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define inf 1e8

typedef long long ll;
inline int read(){
    register int num = 0;
    register char ch = getchar();
    while ( ch > '9' || ch < '0' ) ch = getchar();
    while ( ch <= '9' && ch >= '0' ) num = num * 10 + ch - '0' , ch = getchar();
    return num;
}
int num[10];
inline void write(int x){
    register int cnt = 0;
    if ( !x ){ printf("0"); return; } //Ò»¶šÒªÌØÅÐ0£¡£¡£¡
    while ( x ) num[++cnt] = x % 10 , x /= 10;
    while ( cnt ) putchar(num[cnt--] + '0');
}
struct node{
    int x,y;
}dt[maxn];
int n,m,q,deg[maxn],sz,tag[maxn],id[maxn],tot,exi[maxn];
ll v[maxn],w[2][1020][1020];
int big[maxn],rev[maxn];
vector <int> vec[maxn];

void init(){
    rep(i,1,n) tag[i] = deg[i] = id[i] = 0 , vec[i].clear();
    rep(i,1,n) v[i] = (ll)rand() * rand() * rand();
    rep(i,0,m / sz) rev[i] = 0;
    rep(i,0,m) exi[i] = 1;
    memset(w,0,sizeof(w));
    tot = 0;
}

inline void update(int i,int cur){
    int x = dt[i].x , y = dt[i].y;
    if ( tag[x] ){
        w[0][cur][id[x]] ^= v[y];
        w[1][cur][id[x]] ^= v[y];
    }
    if ( tag[y] ){
        w[0][cur][id[y]] ^= v[x];
        w[1][cur][id[y]] ^= v[x];
    }
}
inline void modify(int l,int r){
    int L = l == 0 ? 0 : ((l - 1) / sz + 1),R = (r + 1) / sz - 1;
    rep(i,L,R){
        rev[i] ^= 1;
    }
    if ( R >= L ){
        rep(i,l,sz * L - 1) exi[i] ^= 1 , update(i,i / sz);
        rep(i,(R + 1) * sz,r) exi[i] ^= 1 , update(i,i / sz);
    }
    else{
        //ÖЌ䲻°üº¬ÈÎÒâÒ»¿éÒªÌØÅÐ
        rep(i,l,r) exi[i] ^= 1 , update(i,i / sz);
    }
}
inline ll cal(int id,int x){
    if ( exi[id] ^ rev[id / sz] ){
        if ( dt[id].x == x ) return v[dt[id].y];
        return v[dt[id].x];
    }
    return 0;
}
ll query(int x){
    ll res = 0;
    if ( tag[x] ){
        rep(i,0,m / sz){
            res ^= w[rev[i]][i][id[x]];
        }
    }
    else{
        for (register int i = 0 ; i < vec[x].size() ; i++){
            res ^= cal(vec[x][i],x);
        }
    }
    return res;
}
int main(){
    freopen("input.txt","r",stdin);
    while ( ~scanf("%d %d",&n,&m) ){
        sz = sqrt(m * 2);
        init();
        rep(i,0,m - 1){
            dt[i].x = read() , dt[i].y = read();
            deg[dt[i].x]++ , deg[dt[i].y]++;
            vec[dt[i].x].push_back((int)i) , vec[dt[i].y].push_back((int)i);
        }
        rep(i,1,n) if ( deg[i] > sz ) tag[i] = 1 , big[++tot] = i , id[i] = tot;;
        rep(i,0,m / sz){
            rep(j,i * sz,min(m - 1,(i + 1) * sz - 1)){
                int x = dt[i].x,y = dt[i].y;
                if ( tag[x] ) w[0][i][id[x]] ^= v[y];
                if ( tag[y] ) w[0][i][id[y]] ^= v[x];
            }
        }
        q = read();
        while ( q-- ){
            int tp,x,y;
            tp = read() , x = read() , y = read();
            if ( tp == 1 ){
                modify(x - 1,y - 1);
            }
            else{
                if ( query(x) == query(y) ) printf("1");
                else printf("0");
            }
        }
        printf("\n");
    }
    return 0;
}

G:NTT优化数位DP

#include<bits/stdc++.h>
using namespace std;
#define maxn 100020
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define inf 1e8

inline int read(){
    register int num = 0;
    register char ch = getchar();
    while ( ch > '9' || ch < '0' ) ch = getchar();
    while ( ch <= '9' && ch >= '0' ) num = num * 10 + ch - '0' , ch = getchar();
    return num;
}
int num[10];
inline void write(int x){
    register int cnt = 0;
    if ( !x ){ printf("0"); return; } //Ò»¶šÒªÌØÅÐ0£¡£¡£¡
    while ( x ) num[++cnt] = x % 10 , x /= 10;
    while ( cnt ) putchar(num[cnt--] + '0');
}

typedef long long ll;
const ll p = 998244353,g = 3;
const int len = 32768,cnt = 15,mod = 10857;
ll f[32][maxn],c[maxn],res[maxn],inv;
int n,rev[maxn];
int a[6] = {2,3,5,7,11,47},t[5] = {1,2,3,5,7};

inline ll power(ll x,ll y,ll p){
    ll res = 1;
    while ( y ){
        if ( y & 1 ) res = res * x % p;
        x = x * x % p;
        y >>= 1;
    }
    return res;
}

void NTT(ll a[],int tag){
    rep(i,0,len - 1) if ( rev[i] > i ) swap(a[rev[i]],a[i]);
    for (register int i = 1 ; i < len ; i <<= 1){
        ll wn = power(g,(p - 1) / (i << 1),p);
        for (register int j = 0 ; j < len ; j += (i << 1)){
            ll w = 1;
            for (register int k = 0 ; k < i ; k++){
                ll x = a[j + k] , y = a[i + j + k] * w % p;
                a[j + k] = (x + y) % p;
                a[i + j + k] = (x - y + p) % p;
                w = w * wn % p;
            }
        }
    }
    if ( tag == -1 ){
        reverse(a + 1,a + len);

        rep(i,0,len - 1) a[i] = inv * a[i] % p;
    }
}
void qpow(ll a[],ll b[],ll n){
    rep(i,0,len - 1) c[i] = 0;
    rep(i,0,len - 1) c[n * i % mod] = (c[n * i % mod] + a[i]) % p;
    NTT(c,1);
    rep(i,0,len - 1) c[i] = c[i] * b[i] % p;
    NTT(c,-1);
    rep(i,0,len - 1) a[i] = 0;
    rep(i,0,len - 1) a[i % mod] = (a[i % mod] + c[i]) % p;
}
void init(){
    inv = power(len,p - 2,p);
    rep(i,0,len - 1){
        int cur = 0;
        rep(j,0,cnt - 1){
            if ( i & (1 << j) ) cur += 1 << (cnt - j - 1);
        }
        rev[i] = cur;
    }
    rep(i,0,4) f[0][t[i]] = 1;
    rep(i,1,29){
        memcpy(f[i],f[i - 1],sizeof(f[i])) , NTT(f[i - 1],1);
        qpow(f[i],f[i - 1],power(10,1 << (i - 1),mod));
    }
    NTT(f[29],1);
}
int check(int x){
    rep(i,0,5) if ( (x % a[i]) == 0 ) return 0;
    return 1;
}
int main(){
//  freopen("input.txt","r",stdin);
    init();
    while ( ~scanf("%d",&n) ){
        n--;
        memset(res,0,sizeof(res));
        res[0] = 1;
        repd(i,29,0){
            if ( n & (1 << i) ) qpow(res,f[i],power(10,1 << i,mod));
        }       
        ll ans = 0;
    //  rep(i,0,10) cout<<res[i]<<" ";
    //  cout<<endl;
        rep(i,0,mod - 1){
            int cnt = 0;
            rep(j,0,4) if ( check(i * 10 + t[j]) ) cnt++;
            ans = (ans + res[i] * cnt) % p;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

H:用圆的包含关系建树,然后DP,明天写

明天目标过3题,进入前5名!提高思维速度,减少代码错误和罚时,静心深入思考!!!
明天早点睡!一刻不能放松!先调完题才能回寝室!

猜你喜欢

转载自blog.csdn.net/weixin_42484877/article/details/81140150