1. 程式人生 > >Lydsy2017省隊十連測

Lydsy2017省隊十連測

ack 不能 nod push tchar bre strong 情況 縮點

5215: [Lydsy2017省隊十連測]商店購物

可能FFT學傻了,第一反應是前面300*300背包,後面FFT...

實際上前面背包,後面組合數即可.只是這是一道卡常題,需要註意常數..

技術分享圖片
 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10
#include<set> 11 #include<map> 12 #define For(i,a,b) for(int i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 14 const int N=307,up=10000000,p=1000000007; 15 typedef long long LL; 16 typedef double db; 17 using namespace std; 18 int n,m,k,w[N],prw; 19 LL fac[up+7],inv[up+7],f[N*N],sum[N],g[up+7
],ans; 20 21 template<typename T> void read(T &x) { 22 char ch=getchar(); x=0; T f=1; 23 while(ch!=-&&(ch<0||ch>9)) ch=getchar(); 24 if(ch==-) f=-1,ch=getchar(); 25 for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f; 26 } 27 28 LL C(int n,int
m) { 29 if(n<m||n<0||m<0) return 0; 30 return fac[n]*inv[m]%p*inv[n-m]%p; 31 } 32 33 LL mo(LL x) { if(x<0) return x+p; if(x>=p) return x-p; return x; } 34 35 //#define DEBUG 36 int main() { 37 #ifdef DEBUG 38 freopen("1.in","r",stdin); 39 //freopen(".out","w",stdout); 40 #endif 41 read(n); read(m); read(k); 42 inv[0]=inv[1]=fac[0]=1; 43 For(i,2,k+n-m) inv[i]=mo(p-p/i*inv[p%i]%p); 44 For(i,1,k+n-m) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p; 45 For(i,1,m) read(w[i]); 46 f[0]=1; 47 For(i,1,m) { 48 sum[0]=1; 49 prw+=w[i]; 50 For(j,1,prw) sum[j]=mo(sum[j-1]+f[j]); 51 Rep(j,prw,0) 52 f[j]=mo(sum[j]-(j-w[i]-1>=0?sum[j-w[i]-1]:0)); 53 } 54 g[0]=1; 55 if(!(n-m)) { 56 if(k<=prw) printf("%lld\n",f[k]); 57 else puts("0"); 58 return 0; 59 } 60 For(i,0,min(prw,k)) 61 ans=mo(ans+f[i]*C(k-i+(n-m)-1,n-m-1)%p); 62 printf("%lld\n",ans); 63 return 0; 64 }
View Code

5216: [Lydsy2017省隊十連測]公路建設

感覺可以lct+回滾莫對亂搞

正解:發現n很小,讓人浮想連篇

線段樹,每個節點維護這段區間的邊可選的情況下在最小生成森林上的邊,n很小所以每個點上的邊都不超過99條

線段樹update的時候用歸並排序,查的時候直接快拍一波.

求最小生產森林的時候並查集維護.

昨天寫的時候對拍十分完美,看了有看也找不出毛病,一直WA.今天重構了下代碼就過了...

技術分享圖片
  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #include<map>
 12 const int N=200007;
 13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 15 typedef long long LL; 
 16 typedef double db;
 17 using namespace std;
 18 int n,m,q;
 19 
 20 template<typename T> void read(T &x) {
 21     char ch=getchar(); x=0; T f=1;
 22     while(ch!=-&&(ch<0||ch>9)) ch=getchar();
 23     if(ch==-) f=-1,ch=getchar();
 24     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
 25 }
 26 
 27 struct edge { int u,v,w; }e[N];
 28 vector<int>vc[N*20];
 29 
 30 #define lc x<<1
 31 #define rc ((x<<1)|1)
 32 #define mid ((l+r)>>1)
 33 
 34 int fa[N];
 35 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
 36 
 37 int sta[N],top;
 38 void update(int x) {
 39     int i=0,j=0,up1=vc[lc].size(),up2=vc[rc].size(); top=0;
 40     while(i<up1||j<up2) {
 41         if(j>=up2||(i<up1&&j<up2&e[vc[lc][i]].w<=e[vc[rc][j]].w)) sta[++top]=vc[lc][i++];
 42         else sta[++top]=vc[rc][j++];    
 43     }
 44     For(i,1,top) {
 45         int u=e[sta[i]].u,v=e[sta[i]].v;
 46         fa[u]=u; fa[v]=v;
 47     }
 48     For(i,1,top) {
 49         int u=e[sta[i]].u,v=e[sta[i]].v;
 50         if(find(u)!=find(v)) {
 51             fa[find(u)]=find(v);
 52             vc[x].push_back(sta[i]);
 53         }
 54     }
 55 } 
 56 
 57 void build(int x,int l,int r) {
 58     if(l==r) { vc[x].push_back(l); return; }
 59     build(lc,l,mid); build(rc,mid+1,r);
 60     update(x);
 61 }
 62 
 63 void qry(int x,int l,int r,int ql,int qr) {
 64     if(l>=ql&&r<=qr) {
 65         int up=vc[x].size();
 66         For(i,0,up-1) sta[++top]=vc[x][i];
 67         return ;
 68     }
 69     if(ql<=mid) qry(lc,l,mid,ql,qr);
 70     if(qr>mid) qry(rc,mid+1,r,ql,qr);
 71 }
 72 
 73 bool cmp(const int &A,const int &B) {
 74     return e[A].w<e[B].w;
 75 }
 76 
 77 int solve(int l,int r) {
 78     top=0; if(l>r) swap(l,r);
 79     qry(1,1,m,l,r);
 80     sort(sta+1,sta+top+1,cmp);
 81     int rs=0,cnt=0;
 82     For(i,1,n) fa[i]=i;
 83     For(i,1,top) {
 84         int u=e[sta[i]].u,v=e[sta[i]].v,w=e[sta[i]].w;
 85         if(find(u)!=find(v)) {
 86             fa[find(u)]=find(v);
 87             rs+=w; cnt++;
 88             if(cnt>=n-1) break;
 89         }
 90     }
 91     return rs;
 92 }
 93 
 94 //#define DEBUG
 95 int main() {
 96 #ifdef DEBUG
 97     freopen("1.in","r",stdin);
 98     //freopen(".out","w",stdout);
 99 #endif
100     read(n); read(m); read(q);
101     For(i,1,m) {
102         read(e[i].u); read(e[i].v); read(e[i].w);
103     }
104     build(1,1,m);
105     while(q--) {
106         int l,r;
107         read(l); read(r);
108         printf("%d\n",solve(l,r));
109     }
110     return 0;
111 }
View Code

5217: [Lydsy2017省隊十連測]航海艦隊

忘了FFT的用處了...

A把圖拉成一維,有障礙的格子設為1

B把艦隊的一整塊矩形移到圖的右下角,拉成一維,有艦的地方設為1

把A和倒置的B FFT求出圖中以哪些格子為右下角的整塊矩形可以放下這個艦隊

$A[pos]= \sum B‘[i]*A[pos-i]$

$A[pos]==0$:pos為右下角的矩形,不存在又是艦又是障礙的格子

根據可不可以放下從右下角的起點開始bfs,找到可以走到的那些右下角

這些點就是實際可以作為右下角的點.

腦子有點木,為了便於理解一開始算的右下角,bfs的時候標記出可以放的是又轉到對應左上角去了

然後bfs後得到的標記數組和不倒置的艦隊數組FFT求出那些點可以到達.$C[pos]= \sum B[i]*C[pos-i]$
當前的$pos$是艦隊中第$i$個,$pos-i$的位置能不能作為左上角.若存在第i個是艦且$pos-i$的位置能作為左上角,即$C[pos]>0$,$pos$可以被到達

技術分享圖片
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define pi acos(-1)
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=707,M=2048576;
typedef long long LL; 
typedef double db;
using namespace std;
char s[N][N];
int lx,ly,rx,ry,n,m,pos,r[M],tx[5]={0,0,1,-1},ty[5]={1,-1,0,0},vis[M];

struct E {
    double x,y;
    E(){}
    E(db x,db y):x(x),y(y){}
    friend E operator +(const E&A,const E&B) { return E(A.x+B.x,A.y+B.y); }
    friend E operator -(const E&A,const E&B) { return E(A.x-B.x,A.y-B.y); }
    friend E operator *(const E&A,const E&B) { return E(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x); }
    friend E operator /(const E&A,const db&B) { return E(A.x/B,A.y/B); }
    /*E operator + (const E &d) const { return E(x+d.x,y+d.y); }
    E operator - (const E &d) const { return E(x-d.x,y-d.y); }
    E operator * (const E &d) const { return E(x*d.x-y*d.y,x*d.y+y*d.x); }
    E operator / (const double &d) const { return E(x/d,y/d); }*/
};
E A[M],B[M],C[M];

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!=-&&(ch<0||ch>9)) ch=getchar();
    if(ch==-) f=-1,ch=getchar();
    for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
}

struct node { 
    int x,y; 
    node(int x,int y):x(x),y(y){}
};

int ok(int x,int y) { 
    return x>=(rx-lx+1)&&x<=n&&y>=(ry-ly+1)&&y<=m&&!vis[(x-1)*m+y-1]&&(A[(x-1)*m+y-1].x==0); 
}

queue<node>que;
void bfs(node s) {
    que.push(s); 
    vis[(s.x-1)*m+s.y-1]=1;
    while(!que.empty()) {
        node tp=que.front();
        que.pop();
        int x=tp.x,y=tp.y,id=(tp.x-1)*m+tp.y-1;
        C[id-(rx-lx+1)*m+1+ly-1+m-ry]=E((A[id].x==0),0);
        For(i,0,3) if(ok(x+tx[i],y+ty[i])) {
            vis[(x+tx[i]-1)*m+y+ty[i]-1]=1;
            que.push(node(x+tx[i],y+ty[i]));
        }
    }
}

void FFT(E a[],int n,int f) {
    For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
    for(int i=1;i<n;i<<=1) {
        E wn(cos(pi/i),f*sin(pi/i));
        for(int j=0,pp=(i<<1);j<n;j+=pp) {
            E w(1,0);
            for(int k=0;k<i;k++,w=w*wn) {
                E x=a[j+k],y=a[j+k+i]*w;
                a[j+k]=x+y; a[j+k+i]=x-y;
            }
        }
    }
    if(f==-1) {
        For(i,0,n-1) a[i].x=(int)(a[i].x/n+0.5);
    }
}

//#define DEBUG 
int main() { 
#ifdef DEBUG 
    freopen("std.in","r",stdin);
    //freopen(".out","w",stdout);
#endif
    read(n); read(m);
    For(i,1,n) scanf("%s",s[i]+1);
    lx=n+1,ly=m+1,rx=0,ry=0;
    For(i,1,n) For(j,1,m) {
            A[(i-1)*m+j-1]=E((s[i][j]==#),0);
            if(s[i][j]==o) lx=min(lx,i),ly=min(ly,j),rx=max(rx,i),ry=max(ry,j); 
        }
    int A_len=n*m-1,B_len=A_len;
    For(i,1,n) For(j,1,m) if(s[i][j]==o) {
        int x=i+(n-rx),y=j+(m-ry);
        B[B_len-((x-1)*m+y-1)]=E(1,0);
    }
    int len=A_len+B_len,nn,ll=0;
    for(nn=1;nn<=len;nn<<=1) ll++;
    For(i,1,nn) r[i]=(r[i>>1]>>1)|((i&1)<<ll-1);
    FFT(A,nn,1); FFT(B,nn,1);
    For(i,0,nn-1) A[i]=A[i]*B[i];
    FFT(A,nn,-1);
    bfs(node(rx,ry));
    For(i,0,nn) B[i]=E(0,0);
    For(i,1,n) For(j,1,m) if(s[i][j]==o) {
        int x=i-lx+1,y=j-ly+1;
        B[(x-1)*m+y-1]=E(1,0);
    }
    FFT(B,nn,1);
    FFT(C,nn,1);
    For(i,0,nn-1) C[i]=C[i]*B[i];
    FFT(C,nn,-1);
    int ans=0;
    For(i,0,n*m-1) if((int)C[i].x) ans++;
    printf("%d\n",ans);
    return 0;
}
View Code

5219: [Lydsy2017省隊十連測]最長路徑

競賽圖的性質:

1.競賽圖存在哈密頓路徑

2.強聯通競賽圖存在哈密頓回路

3.競賽圖縮點後形成一條鏈

證明:數學歸納法

寫得非常好的題解

技術分享圖片
 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=2007;
15 typedef long long LL; 
16 typedef double db;
17 using namespace std;
18 int n,p;
19 LL f[N],g[N],power[N*N],C[N][N],ans[N];
20 
21 template<typename T> void read(T &x) {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!=-&&(ch<0||ch>9)) ch=getchar();
24     if(ch==-) f=-1,ch=getchar();
25     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
26 }
27 
28 //#define DEBUG
29 int main() {
30 #ifdef DEBUG
31     freopen("1.in","r",stdin);
32     //freopen(".out","w",stdout);
33 #endif
34     read(n); read(p);
35     power[0]=1;
36     For(i,1,n*n) power[i]=power[i-1]*2%p;
37     For(i,0,n) C[i][0]=1;
38     For(i,1,n) For(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
39     int up=n*(n-1)/2;
40     f[0]=1;
41     For(i,1,n) f[i]=power[i*(i-1)/2];
42     For(i,1,n) {
43         g[i]=f[i];
44         For(j,1,i-1) g[i]=(g[i]-C[i][j]*g[j]%p*f[i-j]%p+p)%p;
45     }
46     For(i,1,n) For(j,0,n) if(i+j<=n) {
47         ans[i+j]=(ans[i+j]+C[n-1][i-1]*g[i]%p*C[n-i][j]%p*f[j]%p*f[n-j-i])%p;
48     }
49     For(k,1,n) printf("%lld\n",ans[k]);    
50     return 0;
51 }
View Code

Lydsy2017省隊十連測