前两天断签了~~~好在洛谷对我好,网开一面。虽然打卡天数没清零,但还是保持在9天。(至少没掉)为了补回前两天的题目,加上今天的题目,一共是三题。这是今天的幸运签:
今天的还不错吧,我天天都写洛谷日报(观众:前两天你不是没写吗?)但是今天我考了两场试成绩都不理想啊~~~
好啦~要题解的看这里:
P1344 [USACO4.4] 追查坏牛奶 Pollutant Control:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define int long long
const int maxn = 10005;
const int maxm = 2e5 + 5;
const int inf = 999999999;
const int mod = 1007;
inline int read()
{
int ans = 0,op = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') op = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
(ans *= 10) += ch - '0';
ch = getchar();
}
return ans * op;
}
struct egde
{
int to,cost,next,other;
}e[maxm];
int fir[maxn],alloc;
void adde(int u,int v,int w)
{
e[++alloc].next = fir[u];
fir[u] = alloc;
e[alloc].to = v;
e[alloc].cost = w * mod + 1;
e[alloc].other = alloc + 1;
swap(u,v);
e[++alloc].next = fir[u];
fir[u] = alloc;
e[alloc].to = v;
e[alloc].cost = 0;
e[alloc].other = alloc - 1;
}
int n,m,s,t;
int cnt,ans;
bool vis[maxn];
int dep[maxn];
bool bfs(int s,int t)
{
memset(dep,0,sizeof(dep));
queue<int> q;
dep[s] = 1;
q.push(s);
while(q.size())
{
int u = q.front();
q.pop();
for(int i = fir[u];i;i = e[i].next)
{
int v = e[i].to,c = e[i].cost;
if(c > 0 && dep[v] == 0 && vis[i] == 0)
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
//for(int i = 1;i <= n;i++) printf("%d %d\n",i,dep[i]);
if(dep[t]) return 1;
else return 0;
}
int find(int u,int f)//在u点,要解决值为f的流量
{
//printf("%d %d\n",u,f);
if(u == t) return f;
int curflow = 0,t = 0;
for(int i = fir[u];i;i = e[i].next)
{
int v = e[i].to,c = e[i].cost;
if(c > 0 && dep[v] == dep[u] + 1 && curflow < f && vis[i] == 0)
{
t = find(v,min(c,f - curflow));
curflow += t;
e[i].cost -= t;
e[e[i].other].cost += t;
}
}
return curflow;
}
main()
{
n = read(),m = read();
for(int i = 1;i <= m;i++)
{
int u = read(),v = read(),w = read();
adde(u,v,w);
}
s = 1,t = n;
while(bfs(s,t))
ans += find(s,inf);
printf("%d ",ans / mod);
printf("%d",ans % mod);
}
P1361 小M的作物:
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#define M 5000000
#define N 2000000
#define INF 0x3f3f3f3f
#define re register
#define int long long//邪教宏定义
#define _ 0
#define drep(k ,l ,r) for(re int k = r ; k >= l ; -- k )
#define rep(k ,l ,r) for(re int k = l ; k <= r ; ++ k)
using namespace std;
int n ,m ,u ,v ,w ,head[N] ,tot = 1 ,s ,t;
int cap ,cnt ,c1 ,c2 ,numb ,pax1 ,pax2 ,tmp;
int high[N] ,gap[N] ,extra[N];//三个数组分别是高度,超额流量,gap优化
bool vis[N];
queue<int> que;
stack<int> sta;
struct edge {
int next ,to ,w;
} e[M];
int read() {
char cc = getchar() ; int cn = 0 ,flus = 1;
while(cc < '0' || cc > '9') {if(cc == '-') flus = - flus ; cc = getchar() ; }
while(cc >= '0' && cc <= '9') cn = cn * 10 + cc - '0' ,cc = getchar();
return flus * cn;
}
void add_sapr(int u ,int v ,int w) {
e[++tot].next = head[u];
head[u] = tot;
e[tot].to = v;
e[tot].w = w;
}
void add(int u ,int v ,int w) {
add_sapr(u ,v ,w) ,add_sapr(v ,u ,0);//建边
}
bool bfs() {//注意这里的bfs是反向bfs,但同样也是判断图的连通性
rep(i ,0 ,N - 1) high[i] = INF;
que.push(t) ,high[t] = 0;
while(!que.empty()) {
u = que.front() ,que.pop();
for(int i = head[u] ; i ; i = e[i].next)
if(e[i ^ 1].w && high[e[i].to] > high[u] + 1) high[e[i].to] = high[u] + 1 ,que.push(e[i].to) ;
}
return high[s] != INF;
}
struct cmp {
bool operator()(int a ,int b) const { return high[a] < high[b]; }
};//重载运算符
priority_queue<int ,vector<int> ,cmp> pri_que;
bool push(int u) {//尽可能多推送超额流
for(int i = head[u] ; i ; i = e[i].next) {
const int wi = e[i].w;
if(!wi || high[u] != high[e[i].to] + 1) continue;
int minn = min(wi ,extra[u]);
extra[u] -= minn ,extra[e[i].to] += minn ,e[i].w -= minn ,e[i ^ 1].w += minn;
if(e[i].to != s && e[i].to != t && !vis[e[i].to]) pri_que.push(e[i].to) ,vis[e[i].to] = 1;// 推送之后,v 必然溢出,则入堆,等待被推送
if(!extra[u]) return 0;//没了就返回
}
return 1;
}
void relabel(int u) {//重新贴高度标签
high[u] = INF;
for(int i = head[u] ; i ; i = e[i].next)
if(e[i].w) high[u] = min(high[u] ,high[e[i].to]);
++high[u];
}
int hlpp() {
if(!bfs()) return 0;
high[s] = n;
rep(i ,0 ,N - 1) if(high[i] != INF) ++gap[high[i]];//gap优化
for(int i = head[s] ; i ; i = e[i].next) {
const int wi = e[i].w;
if(!wi) continue;
extra[s] -= wi ,extra[e[i].to] += wi ,e[i].w -= wi ,e[i ^ 1].w += wi;
if(e[i].to != s && e[i].to != v && !vis[e[i].to]) pri_que.push(e[i].to) ,vis[e[i].to] = 1;
}
while(!pri_que.empty()) {
int u = pri_que.top();
pri_que.pop() ,vis[u] = 0;
while(push(u)) {
if(!(--gap[high[u]])) //gap优化(如果 u 结点原来所在的高度没有结点了,相当于出现断层)
rep(i ,1 ,n)
if(i != s && i != t && high[i] > high[u] && high[i] < n + 1) high[i] = n + 1;
relabel(u);
++gap[high[u]];
}
}
return extra[t];//返回超额流
}
signed main() {
n = read();t = n + 1;
rep(i ,1 ,n) cap = read() ,add(s ,i ,cap) ,cnt += cap;
rep(i ,1 ,n) cap = read() ,add(i ,t ,cap) ,cnt += cap;
m = read();pax1 = n + 2 ,pax2 = n + 3;
rep(i ,1 ,m) {
numb = read() ,c1 = read() ,c2 = read();
cnt = cnt + c1 + c2;
add(s ,pax1 ,c1) ,add(pax2 ,t ,c2);
rep(i ,1 ,numb) tmp = read() ,add(pax1 ,tmp ,INF) ,add(tmp ,pax2 ,INF);
pax1 += 2 ,pax2 += 2;//虚点更新
}
printf("%lld" ,cnt - hlpp());//答案即为总和减去最小割
return ~~(0^_^0);
}
P1393 Mivik 的标题:
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define pn putchar('\n')
#define maxint 2147483647
#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
#define maxn 1000005
#define mod 998244353
#define I 86583718LL
#define g 3
#define int ll
using namespace std;
il void upd(int &x,int y)
{
x+=y;
if(x>=mod)x-=mod;
if(x<0)x+=mod;
}
il int ksm(int x,int y)
{
int ret=1;
while(y)
{
if(y&1)ret=ret*x%mod;
x=x*x%mod,y>>=1;
}
return ret;
}
namespace polynomial
{
int gn[maxn],gi[maxn],rev[maxn],iv[maxn];
il void init()
{
for(int i=1;i<=1e6;i<<=1)
gn[i]=ksm(g,(mod-1)/i),gi[i]=ksm(gn[i],i-1);
iv[0]=iv[1]=1;
for(int i=2;i<=1e6;i++)
iv[i]=(mod-mod/i)*iv[mod%i]%mod;
}
il int getn(int n)
{
return 1<<(int)ceil(log2(n));
}
il void getrev(int n)
{
for(int i=0;i<n;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)?n>>1:0);
}
il void print(int *a,int n)
{
for(int i=0;i<n;i++)
printf("%lld ",a[i]);
pn;
}
il void add(int *a,int *b,int n)
{
for(int i=0;i<n;i++)
upd(a[i],b[i]);
}
il void px(int *a,int *b,int n)
{
for(int i=0;i<n;i++)
a[i]=a[i]*b[i]%mod;
}
il void cpy(int *a,int *b,int n)
{
for(int i=0;i<n;i++)
a[i]=b[i];
}
il void clr(int *a,int n)
{
for(int i=0;i<n;i++)
a[i]=0;
}
il void NTT(int *a,int n,int ty=1)
{
for(int i=0;i<n;i++)
if(rev[i]<i)
swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1)
{
int y=ty==1?gn[i<<1]:gi[i<<1];
for(int j=0;j<n;j+=i<<1)
{
int x=1;
for(int k=j;k<j+i;k++,x=x*y%mod)
{
int l=a[k],r=x*a[k+i]%mod;
a[k]=l+r,a[k+i]=l-r;
a[k]=a[k]>=mod?a[k]-mod:a[k];
a[k+i]=a[k+i]<0?a[k+i]+mod:a[k+i];
}
}
}
if(ty==-1)
{
for(int i=0;i<n;i++)
a[i]=a[i]*iv[n]%mod;
}
}
il void ch(int *a,int* F,int* G,int n)
{
getrev(n);
NTT(F,n);
NTT(G,n);
for(int i=0;i<n;i++)
a[i]=F[i]*G[i]%mod;
NTT(a,n,-1);
}
static int tni[maxn],tni2[maxn];
il void bni(int *a,int *b,int n)
{
if(n==1)
{
b[0]=ksm(a[0],mod-2);
return;
}
cpy(tni2,a,n),cpy(tni,b,n);
ch(tni,tni,tni2,n);
clr(tni,n>>1);
cpy(tni2,b,n);
ch(tni,tni,tni2,n);
for(int i=n>>1;i<n;i++)
b[i]=tni[i]?mod-tni[i]:0;
}
il void ni(int *a,int *b,int n)
{
n=getn(n<<1);
clr(b,n);
for(int len=1;len<n;len<<=1)
bni(a,b,len);
}
}
using namespace polynomial;
int n,k,m;
int a[maxn],F[maxn],G[maxn],nex[maxn];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
init();
scanf("%lld%lld%lld",&n,&k,&m);
for(int i=1;i<=m;i++)
scanf("%lld",&a[i]);
for(int i=2,j=0;i<=m;i++)
{
while(j&&a[j+1]!=a[i])
j=nex[j];
if(a[j+1]==a[i])
j++;
nex[i]=j;
}
for(int i=m;i;i=nex[i])
F[m-i]++;
ni(F,G,n+1);
for(int i=n;i>=m;i--)
G[i]=G[i-m];
for(int i=0;i<m;i++)
G[i]=0;
G[0]=1;
G[1]=(mod-k+G[1])%mod;
ni(G,F,n+1);
printf("%lld",(ksm(k,n)-F[n]+mod)%mod*ksm(k,n*(mod-2))%mod);
return 0;
}
记得三连哟!