能写一点是一点吧
多校第一场由于某些不可抗力因素就没打
1001:
我们考虑dp[i][j][k][now](i<j<k<now)表示这四种颜色出现的最后的位置为i,j,k,now的方案数
细节再稍微注意一下就行了
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int N=110;
int n,m,T,l,r,x;
int a[N][N][2],f[2][N][N][N];
void add(int &x,int y){x=(x+y)%mod;}
int main() {
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=4;j++) a[i][j][0]=mod,a[i][j][1]=0;
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&l,&r,&x);
a[r][x][0]=min(a[r][x][0],l);
a[r][x][1]=max(a[r][x][1],l);
}
memset(f[0],0,sizeof(f[0]));
f[0][0][0][0]=1;
for (int i=0;i<n;i++){
for (int j=a[i+1][2][1];j<a[i+1][1][0]&&j<(i+1);j++)
for (int k=a[i+1][3][1];(k<a[i+1][2][0]&&k<j)||(k==0&&j==0);k++)
for (int p=a[i+1][4][1];(p<a[i+1][3][0]&&p<k)||(p==0&&k==0);p++) f[(i&1)^1][j][k][p]=0;
for (int j=a[i][2][1];(j<a[i][1][0]&&j<i)||(j==0&&i==0);j++)
for (int k=a[i][3][1];(k<a[i][2][0]&&k<j)||(k==0&&j==0);k++)
for (int p=a[i][4][1];(p<a[i][3][0]&&p<k)||(p==0&&k==0);p++){
add(f[(i&1)^1][j][k][p],f[i&1][j][k][p]);
add(f[(i&1)^1][i][k][p],f[i&1][j][k][p]);
add(f[(i&1)^1][i][j][p],f[i&1][j][k][p]);
add(f[(i&1)^1][i][j][k],f[i&1][j][k][p]);
}
}
int ans=0;
for (int j=a[n][2][1];(j<a[n][1][0]&&j<n);j++)
for (int k=a[n][3][1];(k<a[n][2][0]&&k<j)||(k==0&&j==0);k++)
for (int p=a[n][4][1];(p<a[n][3][0]&&p<k)||(p==0&&k==0);p++)
add(ans,f[n&1][j][k][p]);
printf("%d\n",ans);
}
}
1002:
[SCOI2016]幸运数字弱化版
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define pb(x) push_back(x)
using namespace std;
const int N=1e6+10;
const int D=30;
int f[N][D+10],a[N],pos[N][D+10];
vector<int>q[N];
int n,m,x,l,r,T,opt,lastans;
void add(int now,int x){
int y=a[x];
for (int i=D;i>=0;i--)
if ((y>>i)&1) {
if (f[now][i]) y^=f[now][i]; else {
f[now][i]=y; pos[now][i]=x; q[now].pb(x); break;
}
}
}
void init(){
for (int i=1;i<=n;i++) {
add(i,i);
for (int j=0;j<q[i-1].size();j++) add(i,q[i-1][j]);
}
}
void solve(int l,int r){
int ans=0;
for (int i=D;i>=0;i--) if ((!((ans>>i)&1))&&pos[r][i]>=l) ans^=f[r][i];
printf("%d\n",ans);
lastans=ans;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
init();
lastans=0;
for (int i=1;i<=m;i++){
scanf("%d",&opt);
if (opt==1) {
scanf("%d",&x); x^=lastans; a[++n]=x;
add(n,n);
for (int j=0;j<q[n-1].size();j++) add(n,q[n-1][j]);
} else {
scanf("%d%d",&l,&r);
l=(l^lastans)%n+1; r=(r^lastans)%n+1;
if (l>r) swap(l,r);
solve(l,r);
}
}
for (int i=1;i<=n;i++) q[i].clear(),memset(f[i],0,sizeof(f[i]));
}
}
1003:先咕着
1004:由于最后一辆车通过线时一定前面有一段连续的车挡着,枚举最前挡着的是哪辆车即可
话说我的写法为什么printf过不去???
#include<bits/stdc++.h>
#define ld long double
#define ll long long
using namespace std;
const int N=2e5+10;
ll l[N],s[N],v[N];
int n,t;
ll len;
ld ans;
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
while (~scanf("%d",&n)){
for (int i=1;i<=n+1;i++) scanf("%lld",&l[i]);
for (int i=1;i<=n+1;i++) scanf("%lld",&s[i]);
for (int i=1;i<=n+1;i++) scanf("%lld",&v[i]);
ans=0; len=0;
for (int i=1;i<=n+1;i++) {
ans=max(ans,(ld)((s[i]+len)*1.0/v[i]));
len+=l[i+1];
}
cout << fixed << setprecision(10) << ans << endl ;
}
// fclose(stdin);
// fclose(stdout);
}
1005:建出最短路图后最小割即可
#pragma GCC optimize("2,Ofast,inline")
#include<bits/stdc++.h>
#define ll long long
#define int long long
#define pb(x) push_back(x)
using namespace std;
const int N=1e4+10;
const int INF=1e17;
struct link{
int u,to,w;
};
link edge[N<<2];
struct node{
int v,u; ll len;
node(int len1=0,int u1=0,int v1=0){len=len1,u=u1,v=v1;}
};
struct cmp{
operator()(const node&a,const node&b){
return a.len>b.len;
}
};
int TI,n,m,x,y,c,k,head[N];
int dist[N];
template <typename T> void read(T &x) {
int f = 0;
register char c = getchar();
while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
for (x = 0; c >= '0' && c <= '9'; c = getchar())
x = (x << 3) + (x << 1) + (c ^ '0');
if (f) x = -x;
}
namespace Maxflow {
const int N = 1e4 + 7;
const int M = 2e5 + 7;
const int inf = 1e17;
int E, V, S, T;
int fir[N], cur[N], dis[N];
int nex[M], arr[M], cap[M];
inline void Add_Edge(int x, int y, int c) {
nex[++E] = fir[x];
fir[x] = E; arr[E] = y; cap[E] = c;
nex[++E] = fir[y];
fir[y] = E; arr[E] = x; cap[E] = 0;
}
int bfs() {
static queue<int> Q;
memset(dis, 0x3f, sizeof(int) * (V + 1));
Q.push(S); dis[S] = 0;
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = fir[x]; i; i = nex[i]) {
if (cap[i] && dis[arr[i]] > dis[x] + 1) {
dis[arr[i]] = dis[x] + 1;
Q.push(arr[i]);
}
}
}
return (dis[T] < inf);
}
int dfs(int x, int mf) {
if (!mf || x == T) return mf;
int ans = 0;
for (int &i = cur[x]; i; i = nex[i]) {
if (cap[i] && dis[arr[i]] == dis[x] + 1) {
int del = dfs(arr[i], min(mf, cap[i]));
ans += del; mf -= del;
cap[i] -= del; cap[i ^ 1] += del;
if (ans == mf) break;
}
}
if (!ans) dis[x] = -1;
return ans;
}
int dinic() {
ll ans = 0;
while (bfs()) {
memcpy(cur, fir, sizeof(int) * (V + 1));
ans += dfs(S, inf);
}
return ans;
}
}
using namespace Maxflow;
void add(int x,int y,int c){
edge[k].u=y; edge[k].to=head[x]; edge[k].w=c; head[x]=k++;
}
void dij() {
priority_queue<node,vector<node>,cmp>q;
for (int i=1;i<=n;i++) dist[i]=INF; dist[1]=0;
for (int i=head[1];i!=-1;i=edge[i].to){
int u=edge[i].u; q.push(node(edge[i].w,u,1));
}
while (!q.empty()){
node v=q.top(); q.pop();
if (dist[v.u]==INF) {
dist[v.u]=v.len;
Add_Edge(v.v,v.u,v.len-dist[v.v]);
dist[v.u]=v.len;
int now=v.u;
for (int i=head[now];i!=-1;i=edge[i].to){
int u=edge[i].u;
q.push(node(dist[now]+edge[i].w,u,now));
}
} else if (dist[v.u]==v.len) {
Add_Edge(v.v,v.u,v.len-dist[v.v]);
}
}
}
signed main(){
scanf("%d",&TI);
while (TI--){
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head)); k=0;
E = 1;
memset(fir, 0, sizeof fir);
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&x,&y,&c);
add(x,y,c);
}
dij();
S=1; T=n; V=n;
printf("%lld\n",dinic());
}
return 0;
}
1006:后缀自动机优化dp即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int rig[N<<1],Max[N<<1],ch[N<<1][26],fa[N<<1],f[N],pos[N];
char s[N];
ll dp[N];
ll w1,w2;
int len,sz,n_last;
void Make_Sam(int c,int id){
int p=n_last,np=++sz;
rig[np]=id;
Max[np]=Max[p]+1; n_last=np;
for (;!ch[p][c]&&p;p=fa[p]) ch[p][c]=np;
if (!p){fa[np]=1;return;}
int q=ch[p][c];
if (Max[q]==Max[p]+1) fa[np]=q;
else {
int nq=++sz; fa[nq]=fa[q]; fa[q]=fa[np]=nq;
Max[nq]=Max[p]+1; rig[nq]=rig[q];
memcpy(ch[nq],ch[q],sizeof(ch[nq]));
for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
void solve(int c,int id){
dp[id]=dp[id-1]+w1;
f[id]=f[id-1]; pos[id]=pos[id-1];
for(;!ch[pos[id]][c]&&pos[id];pos[id]=fa[pos[id]]) f[id]=Max[fa[pos[id]]];
if (!pos[id]) {
pos[id]=1; return;
}
pos[id]=ch[pos[id]][c]; f[id]++;
while ((rig[pos[id]]==id||rig[pos[id]]>=id-f[id]+1)&&f[id]) {
f[id]--; if (f[id]==Max[fa[pos[id]]]) pos[id]=fa[pos[id]];
}
if (!f[id]) {pos[id]=1;return;}
dp[id]=min(dp[id-f[id]]+w2,dp[id]);
}
int main() {
while (~scanf("%s",s+1)){
len=strlen(s+1);
scanf("%lld%lld",&w1,&w2);
sz=n_last=1; pos[0]=1;
for (int i=1;i<=len;i++) Make_Sam(s[i]-'a',i),solve(s[i]-'a',i);
printf("%lld\n",dp[len]);
for (int i=1;i<=sz;i++) memset(ch[i],0,sizeof(ch[i])),Max[i]=fa[i]=dp[i]=f[i]=pos[i]=0;
}
}
1007:他咕了
1008:这题......
1009:贪心选最小的,暴力判合法性
#include<bits/stdc++.h>
#define ll long long
#define pb(x) push_back(x)
using namespace std;
const int N=1e5+10;
const int M=26;
int l[M],r[M];
int f[N][M];
char s[N];
int k,len;
vector<int>q[M];
bool pan(int now,int c){
l[c]--; r[c]--;
int ans=0,sum=0;
for (int i=0;i<M;i++)
if (f[now+1][i]>=l[i]) ans+=min(f[now+1][i],r[i]),sum+=max(l[i],0); else {
l[c]++; r[c]++;
return 0;}
l[c]++; r[c]++;
return ans>=k-1&&k-1>=sum;
}
int main() {
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
while (~scanf("%s",s+1)){
scanf("%d",&k);
len=strlen(s+1);
for (int i=0;i<M;i++) scanf("%d%d",&l[i],&r[i]);
memset(f[len+1],0,sizeof(f[len+1]));
for (int i=len;i>=1;i--) {
for (int j=0;j<M;j++) f[i][j]=f[i+1][j];
f[i][s[i]-'a']++;
}
for (int i=len;i>=1;i--) q[s[i]-'a'].pb(i);
int now=0;
while (k){
bool p=0;
for (int i=0;i<M;i++)
while (!q[i].empty()&&q[i][q[i].size()-1]<=now) q[i].pop_back();
for (int i=0;i<M;i++)
if (!q[i].empty()&&r[i]>0&&pan(q[i][q[i].size()-1],i)){
k--; now=q[i][q[i].size()-1]; p=1; l[i]--; r[i]--; putchar('a'+i); break;
}
if (!p) break;
}
if (k) puts("-1"); else puts("");
for (int i=0;i<M;i++) q[i].clear();
}
// fclose(stdin);
// fclose(stdout);
}
1010:他咕了
1011:他咕了
1012:对于这三种操作,考虑生成函数,然后乘起来牛顿二项式展开即可,做三遍NTT
#include<bits/stdc++.h>
#define ll long long
#define mk(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define cs const
using namespace std;
cs int g=3;
const int N=6e5+10;
const int mod=998244353;
typedef vector<int> poly;
int rev[N],inv[N],c[N],fac[N];
int s[5];
int n,m,len,d,x,k,T;
poly a;
int mul(int x,int y){return (ll)x*y%mod;}
int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int dec(int x,int y){return x-y>=0?x-y:x-y+mod;}
int ksm(int x,int y){
ll ans=1;
for (;y;y>>=1,x=mul(x,x)) if (y&1) ans=mul(ans,x);
return ans;
}
void in_it(){
fac[0]=1;
for (int i=1;i<N;i++) fac[i]=mul(fac[i-1],i);
inv[0]=inv[1]=1;
for (int i=2;i<N;i++) inv[i]=mul(inv[mod%i],(mod-mod/i));
for (int i=1;i<N;i++) inv[i]=mul(inv[i],inv[i-1]);
}
void init(int x){
len=1,d=0;
while (len<x) {len<<=1;d++;}
for (int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(d-1));
}
int BSGS(int X,int Y){
int now=floor(sqrt(mod));
int s=ksm(X,now);
map<int,int>mp;
int t=1;
int sum=Y;
for (int i=0;i<now;i++){
mp[sum]=i; sum=mul(sum,X);
}
int s1=1;
for (int i=0;i<mod;i+=now){
s1=mul(s1,s);
if (mp[s1]) return i+now-mp[s1];
}
}
int lalala(int x){
int now=BSGS(g,x);
return ksm(g,now/2);
}
void out(poly a){
for (int i=0;i<a.size();i++) printf("%d ",a[i]);
puts("\n");
}
inline poly NTT(poly a,int t) {
for (int i=0;i<a.size();i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=1;i<a.size();i<<=1) {
int s=(i<<1);
int wn=ksm(g,(mod-1)/s);
if (t==-1) wn=ksm(wn,mod-2);
for (int j=0;j<a.size();j+=s) {
int w=1;
for (int k=j;k<j+i;k++) {
int x=a[k],y=mul(a[k+i],w);
a[k]=add(x,y); a[k+i]=dec(x,y);
w=mul(w,wn);
}
}
}
if (t==-1){
ll w=ksm(a.size(),mod-2);
for (int i=0;i<a.size();i++) a[i]=mul(a[i],w);
}
return a;
}
inline poly get_down(poly a){
for (int i=0;i<a.size()-1;i++) a[i]=mul(a[i+1],i+1);
a.pop_back();
return a;
}
inline poly get_up(poly a){
a.push_back(0);
for (int i=a.size()-1;i>0;i--) a[i]=mul(a[i-1],inv[i]);
a[0]=0;
return a;
}
inline poly operator +(poly a,poly b){
a.resize(max(a.size(),b.size()));
b.resize(max(a.size(),b.size()));
for (int i=0;i<a.size();i++) a[i]=add(a[i],b[i]);
return a;
}
inline poly operator -(poly a,poly b){
a.resize(max(a.size(),b.size()));
b.resize(max(a.size(),b.size()));
for (int i=0;i<a.size();i++) a[i]=dec(a[i],b[i]);
return a;
}
inline poly operator *(poly a,int x){
for (int i=0;i<a.size();i++) a[i]=mul(a[i],x);
return a;
}
inline poly operator *(poly a,poly b){
int n=a.size(),m=b.size();
init(n+m-1);
a.resize(len);
b.resize(len);
a=NTT(a,1); b=NTT(b,1);
for (int i=0;i<a.size();i++) a[i]=mul(a[i],b[i]);
a=NTT(a,-1);
a.resize(n+m-1);
return a;
}
inline poly get_inv(poly a){
poly b,d;
b.pb(ksm(a[0],mod-2)); d.pb(a[0]);
int now=1;
while (now<a.size()) {
now<<=1;
poly c=b;
c=c*c;
for (int i=(now>>1);i<now&&i<a.size();i++) d.pb(a[i]);
c=c*d;c.resize(now);
b=b*2; b=b-c;
}
b.resize(a.size());
return b;
}
inline poly ln(poly a){poly c=get_up(get_inv(a)*get_down(a));c.resize(a.size());return c;}
inline poly exp(poly a){
poly b,d;
b.pb(1); d.pb(a[0]);
int now=1;
while (now<a.size()){
now<<=1;
for (int i=(now>>1);i<now&&i<a.size();i++) d.pb(a[i]);
poly c=b;
c.resize(now);
c=ln(c)-d;
for (int i=0;i<c.size();i++) c[i]=(mod-c[i])%mod;
c[0]=add(c[0],1);
b=b*c; b.resize(now);
}
b.resize(a.size());
return b;
}
/*
inline poly ksm(poly a,int k){return exp(ln(a)*k);}
inline poly Sqrt(poly a){
poly b,d;
b.pb(lalala(a[0])); d.pb(a[0]);
b[0]=min(b[0],mod-b[0]);
int now=1;
while (now<a.size()){
now<<=1; poly c=b;
for (int i=(now>>1);i<now&&i<a.size();i++) d.pb(a[i]);
c.resize(now);
c=get_inv(c);
c=c*d;c.resize(now);
b=b+c;
for (int i=0;i<now;i++) b[i]=mul(b[i],inv[2]);
}
b.resize(a.size());
return b;
}
*/
int C(int x,int y){
if (x<y||x<0||y<0) return 0;
return mul(mul(fac[x],inv[y]),inv[x-y]);
}
void solve(){
for (int i=1;i<=3;i++){
poly b;
c[0]=1;
for (int j=1;j<=n;j++) if (j%i==0) c[j]=C(s[i]+j/i-1,j/i); else c[j]=0;
for (int j=0;j<=n;j++) b.pb(c[j]);
// out(b);
a=a*b; a.resize(n+1);
}
// out(a);
ll ans=0;
for (int i=1;i<=n;i++) ans^=((ll)a[i]*i);
printf("%lld\n",ans);
}
int main(){
scanf("%d",&T);
in_it();
// cout << fac[3] << endl;
while (T--){
scanf("%d%d",&n,&m);
s[1]=s[2]=s[3]=0;
a.pb(0);
for (int i=1;i<=n;i++) scanf("%d",&x),a.pb(x);
for (int i=1;i<=m;i++) {scanf("%d",&x); s[x]++;}
solve();
a.clear();
}
}
1013:他咕了