ecfinal2020 部分題解

2022-09-19 04:03:11 字數 4065 閱讀 4645

//考慮計算最後四位 momo 的方案數,有乙個狀態數 n*62*62 的 dp,但是每次有用的只有 n*62 個,暴力轉移即可

//前面的方案容斥一下就好了

#include using namespace std;

const int n=1000005;

const int mod=998244353;

char s[n];int a[n];

int f[65][65][3];

int pre[n][65],suf[65];

int to(char x)

void add(int&x,int y)

int tot=1ll*(i-1)*(i-2)/2ll%mod;

for (int j=0;j<62;j++) add(tot,mod-1ll*pre[i-1][j]*(pre[i-1][j]-1)/2%mod);

for (y=0;y<62;y++)

suf[a[i]]++;

} printf ("%d",ans);

return 0;

}

/*

離線,考慮乙個矩形如果在時刻 t 內部出現了被刪掉的點,那麼它的貢獻是字首 [1,t-1]

所以只需要計算有多少個矩形在時刻 t 被刪掉,然後做字首和就是答案

那麼列舉上下行邊界,計算每個列最小值出現次數,這是經典問題,對左右維護能延申的單調棧

時間複雜度 o(n^2m)

*/ #include using namespace std;

const int n=505;

int a[n][n],mn[n],l[n],r[n],s[n],top=0;

long long ans[n*n];

int main()

for (int i=1;i<=n;i++)

top=0;

for (int k=m;k>=1;k--)

for (int k=1;k<=m;k++) ans[mn[k]-1]+=1ll*(k-l[k]+1)*(r[k]-k+1);

} }for (int i=n*m-1;i>=0;i--) ans[i]+=ans[i+1];

for (int i=1;i<=n*m;i++) printf ("%lld\n",ans[i]);

return 0;

}

/*

我們可以確定每個隨機的結果是什麼

預處理 now[i][j] 表示第 i 次操作時,第 j 位是原種子哪些位 0/1 異或起來的結果

顯然,若乙個模數的後 x 位都是 0,那麼取模的結果在二進位制下就是原數後面的那些位

這樣對於所有為 2,4,8,16... 倍數的模數,可以確定一些方程,這樣方程的個數在 n=50 時共有 47 個

使用線性基維護這些方程,暴力列舉自由元,直接 check 即可

這樣看上去是 2^17*n 的,但是實際上如果不是那個種子,check 幾項就會出現問題,遠遠達不到 n 的複雜度

*/#include using namespace std;

const int n=100005;

#define ll unsigned long long

int n;

void rand(ll&x)

int a[n],p[n];

int val[n];

bool check(ll x)

return true;

}bitset <64> bit[64];

bool ans[64];

void dfs(int x)else

}void insert(bitset <64> now,bool v)

else now^=bit[i],v^=ans[i];

}}bitset <64> now[64];

int main()

for (int i=n;i>=1;i--)val[1]=1;

for (int i=1;i<=n;i++) val[i]--;

for (int i=0;i<64;i++) now[i][i]=1;

for (int i=1;i<=n;i++)

} dfs(0);

return 0;

}

//列舉兩條路徑的交集,三分分配權值

#include using namespace std;

const int n=5005;

int head[n],next[n<<1],adj[n<<1],tot=0;

void addedge(int u,int v)

queue q;

int dis[n][n];

const int inf=10000;

void bfs(int x)

}int n,m,k;

double check(int d1,int d2,int x,int y)else sum+=d1;

if (d2)else sum+=d2;

return sum;

}double calc(int x,int y)a[n];

bool cmp1(node a,node b)t[n<<2];

#define mid ((l+r)>>1)

void pushup(int root)

void pushdown(int root)

if (t[root].tg0)

if (t[root].tg1)

}void update(int root,int l,int r,int l,int r)

pushdown(root);

update(root<<1,l,mid,l,r);

update((root<<1)|1,mid+1,r,l,r);

pushup(root);

}long long query(int root,int l,int r,int l,int r)

void build(int root,int l,int r)

build(root<<1,l,mid);

build((root<<1)|1,mid+1,r);

pushup(root);

}#undef mid

int a[n],lst[n];

long long ans[n];

struct queryq[n];

bool cmp(query a,query b)

int flag=-1;

for (int i=0;i<4;i++)

for (int j=2;j+4<=14;j++)

if (c[i][j]&&c[i][j+1]&&c[i][j+2]&&c[i][j+3]&&c[i][j+4])

if (flag!=-1) break;

} if (flag==-1)

for (int i=0;i<2;i++)

for (int i=0;i<4;i++)

if (flag==-1) break;

} if (flag==-1) puts("check");

else puts("allin");

} return 0;

}

#include using namespace std;

const int n=1000005;

int p[n],tot=0;bool notp[n];

void getp() }}

const int mod=1e9+7;

inline int qpow(int a,int b)

return ans;

}int val[n];

int main()

} val[x]++;

}int ans=1;

for (int i=2;i<=1000000;i++) ans=1ll*ans*qpow(i,min(val[i],n-val[i]))%mod;

printf ("%d",ans);

return 0;

}

IOI2020 部分題解

乙個 n 個點的無向圖,給定每兩個點之間的簡單路徑條數 p 構造乙個滿足要求的無向圖或判斷無解。1 le n le10 3,0 le p le 3 這個 p 3 非常煩,但是可以發現若 p 3 則無解。考慮乙個最簡單的情況 其它情況一定可以從這種情況加一些點得到 2 到 4 有 3 條路徑,則 1 ...

Grakn Forces 2020部分題解

要求從三個陣列中每個位置取乙個數字,構成乙個相同長度的陣列,要求相鄰的不相等 環形 那麼我們直接暴力選,記錄當前不能取的值就可以了,然後要記得特判一下首位的兩個元素。首先通過模擬樣例我們發現相同的元素其實是一點用都沒有的,所以我們先去重了再說,然後我們的做法就是貪心的取四個不同的元素一直到取完為止。...

icpc上海站2020部分題解

第一次icpc比賽,最後是以3題300多名的成績直接打鐵,很可惜,d題賽後才知道是精度的問題,不然估計可以拿銅。從比賽中也能得到很多經驗與教訓。1.選好賽區,少打兩年。這次站除去打星隊都有600多隊,只有210個牌,聽說濟南站只有500隊牌子數跟上海站一樣,枯了。2.這次思維題有足足5題,全做了可以...