西安十五日游day10 分治

19 篇文章 0 订阅
17 篇文章 1 订阅

CodeForces 484E Sign on Fence

填坑

UVALive 7469 Distance on Triangulation

给一个三角剖分后的凸包(n<=50000),10^5次询问,问你某2点的最短路。
选一条边AB把图分成2半,那么如果
两个点不在同侧,那么最短路至少经过A,B中的一个,可以用2次bfs搞定,
两个点在同侧但经过A或B,也可以如此搞定
两个点在同侧但不经过A或B,分治做下去
我这里用的是重构图的方法

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (100000+10)
int n;
struct edge{
    int u,v;
    edge(int _u,int _v):u(_u),v(_v){}
    edge(){}
};
struct ask{
    int l,r,i;
    ask(int _l,int _r,int _i):l(_l),r(_r),i(_i){}
    ask(){}
};
int ans[MAXN];
bool inside(int i,int l,int r) {
    if (l<=r) return l<=i&&i<=r;
    else return i>=l||i<=r;
}
int len(int l,int r,int n){
    if (l<=r) return r-l+1;
    return n-(l-r-1);
}
vi e[MAXN];
void bfs(vector<edge> &edges,vector<int> &d,int n,int s) {
    queue<int> q;
    Rep(i,n) d[i]=INF;
    d[s]=0; q.push(s);
    int sz=edges.size();
    Rep(i,sz) {
        e[edges[i].u].pb(edges[i].v);
        e[edges[i].v].pb(edges[i].u);
    }
    Rep(i,n) e[i].pb((i+1)%n),e[(i+1)%n].pb(i);
    while(!q.empty()) {
        int x=q.front(); q.pop();
        Rep(j,e[x].size()) {
            int v=e[x][j];
            if (d[v]==INF) {
                d[v]=d[x]+1;
                q.push(v);
            }
        } 
    }
    Rep(i,n) e[i].clear();
}
void work(vector<edge> &edges,int n,vector<ask> &q) {
    if (edges.empty()) {
        int sz2=SI(q);
        Rep(i,sz2) {
            ask now=q[i];
            ans[now.i]=min(ans[now.i],min(len(now.l,now.r,n)-1,len(now.r,now.l,n)-1));
        }
        return;
    }
    int sz=SI(edges);
    int r=0;
    Rep(i,sz) {
        int u=edges[i].u,v=edges[i].v;
        if (max(len(u,v,n),len(v,u,n))<max(len(edges[r].u,edges[r].v,n),len(edges[r].v,edges[r].u,n))) {
            r=i;
        }
    }
    int L=edges[r].u,R=edges[r].v;
    if(L>R) swap(L,R);
    int sz2=SI(q);
    vi d(n);
    bfs(edges,d,n,L);
    Rep(i,sz2) ans[q[i].i]=min(ans[q[i].i],d[q[i].l]+d[q[i].r]);
    bfs(edges,d,n,R);
    Rep(i,sz2) ans[q[i].i]=min(ans[q[i].i],d[q[i].l]+d[q[i].r]);

    vector<edge> e1,e2;
    vector<ask> q1,q2;
    Rep(i,sz2) {
        ask now=q[i];
        if (now.l==L||now.r==L||now.l==R||now.r==R) continue;
        int fl=inside(now.l,L,R),fl2=inside(now.r,L,R);
        if (fl&&fl2) {
            q1.pb(ask(now.l-L,now.r-L,now.i));
        }
        int fl3=inside(now.l,R,L),fl4=inside(now.r,R,L);
        if (fl3&&fl4){
            q2.pb(ask((now.l-R+n)%n,(now.r-R+n)%n,now.i));
        }
    }
    Rep(i,sz) if (i^r) {
        int u=edges[i].u,v=edges[i].v;
        int fl=inside(u,L,R),fl2=inside(v,L,R);
        if (fl&&fl2) {
            e1.pb(edge(u-L,v-L));
        }
        else {
            e2.pb(edge((u-R+n)%n,(v-R+n)%n));
        }       
    }
    work(e1,len(L,R,n),q1);
    work(e2,len(R,L,n),q2);
}

vector<edge> edges;
vector<ask> q;
int main()
{
//  freopen("data.out","r",stdin);
//  freopen("B.out","w",stdout);
    while(cin>>n) {
        edges.clear();q.clear();
        Rep(i,n-3) {
            int u=read(),v=read();
            u--,v--;
            edges.pb(edge(u,v));
        }
        int m=read();
        For(i,m) {
            int l=read(),r=read();
            l--,r--;
            q.pb(ask(l,r,i));
        }
        For(i,m) ans[i]=INF;
        work(edges,n,q);
        For(i,m)
            printf("%d\n",ans[i]);
    }

    return 0;
}

HDU 4812 D Tree

树上每一个点有一个数字,找一条链使其上的数乘积mod F=K(F是质数)
经典题
Hint:树分治,对每一个节点Hash乘积,显然 dp[x]v[root]=Kdp[y]1(modF)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define F (1000003)
#define MAXN (100000+10)
#define MAXM (200000+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int n;
int edge[MAXM],Next[MAXM]={0},pre[MAXN]={0},size=0;
void addedge(int u,int v)
{
    edge[++size]=v;
    Next[size]=pre[u];
    pre[u]=size;
}
void addedge2(int u,int v){addedge(u,v),addedge(v,u);}
int v[MAXN],K;
int opt[MAXN],siz[MAXN],val[MAXN]={0},all[MAXN],tot=0;
void dfs(int x,int fa)
{
    siz[x]=1;opt[x]=0;all[++tot]=x;
    Forp(x)
    {
        int &v=edge[p];
        if (v^fa&&!val[v])
        {
            dfs(v,x);siz[x]+=siz[v];
            opt[x]=max(opt[x],siz[v]);
        }
    }
}
int h[F]={0},b[F]={0};
int cas=0;
ll pow2(ll a,int b,ll p)  //a^b mod p 
{  
    if (b==0) return 1%p;  
    if (b==1) return a%p;  
    ll c=pow2(a,b/2,p)%p;  
    c=c*c%p;  
    if (b&1) c=c*a%p;  
    return c%p;  
}  
ll Inv(ll a,ll p) { //gcd(a,p)=1
    return pow2(a,p-2,p);
}
ll inv[F]; 
void prework() {
    Rep(i,F) inv[i]=Inv(i,F);
}
void dfs_calc(int x,int fa,ll t,int cas)
{
    t=mul(t,v[x]);
    if (b[t]!=cas||h[t]>x) h[t]=x,b[t]=cas;
    Forp(x)
    {
        int &v=edge[p];
        if (v^fa&&!val[v])
        {
            dfs_calc(v,x,t,cas);

        }
    }
}
pi ans;
void upd(pi &v,pi t) {
    if (t.se==t.fi) return;
    if (t.se<t.fi) swap(t.se,t.fi);
    v=min(v,t);
}
void dfs_calc2(int x,int fa,ll t,int cas)
{
    t=mul(t,inv[v[x]]);
    if (b[t]==cas) {
        upd(ans,mp(x,h[t]));
    }
    Forp(x)
    {
        int &v=edge[p];
        if (v^fa&&!val[v])
        {
            dfs_calc2(v,x,t,cas);

        }
    }
}
void solve(int root,int l)
{
    tot=0,dfs(root,0);
    int minopt=INF,minoptx=0;
    For(i,tot)
    {
        int u=all[i];
        opt[u]=max(opt[u],tot-siz[u]);
        if (minopt>opt[u]) minopt=opt[u],minoptx=u;
    }
    val[root=minoptx]=l;

    ++cas;
    Forp(root) {
        int &V=edge[p];
        if (!val[V]) {
            dfs_calc2(V,root,K,cas); 
            dfs_calc(V,root,v[root],cas);
        }
    }   
    if (b[K]==cas) upd(ans,mp(root,h[K]));

    Forp(root)
    {
        int &v=edge[p];
        if (!val[v]) solve(v,l+1);
    }
}
int main()
{
//  freopen("D.in","r",stdin);
    prework();
    while(cin>>n>>K) {
        MEM(edge) MEM(Next) MEM(pre) size=0;
        MEM(opt) MEM(siz) MEM(val) 
        For(i,n) v[i]=read();
        For(i,n-1)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge2(u,v);
        }
        ans=mp(INF,INF); 
        solve(1,1);
        if (ans==mp(INF,INF)) puts("No solution");
        else {
            printf("%d %d\n",ans.fi,ans.se);
        }

    }
    return 0;
}

CodeForces 97B Superset

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int n;
#define MAXN (200000+10)
pi a[MAXN];
int t[MAXN];
int find(int x) { return lower_bound(t,t+n,x)-t;}
void f(int l,int r) {
    if (l==r) return;
    int m=(l+r)/2;
    Fork(i,l,r) a[n++]=mp(a[m].fi,a[i].se);
    if (l<=m) f(l,m);
    if (m+1<=r) f(m+1,r);   
} 
int main()
{
//  freopen("E.in","r",stdin);
//  freopen(".out","w",stdout);
    cin>>n;
    Rep(i,n) a[i].fi=read(),a[i].se=read();
    sort(a,a+n);
    f(0,n-1);
    sort(a,a+n);
    int m=unique(a,a+n)-a;
    cout<<m<<endl;
    Rep(i,m) cout<<a[i].fi<<' '<<a[i].se<<endl;


    return 0;
}

OpenJ_POJ C15C Rabbit’s Festival

给一张无向图0 ≤ N, 0 ≤ M ≤ 200000,有K天,第i条路第 ci 天关闭
K ≤ 100000
求每天互相可达的点对数

并查集+cdq
记得必须按秩合并,回滚数组(不然会是 O(n2lognα(n)) 的)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
#define MAXN (100000+10)
#define MAXM (200000+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
struct node{
    int u,v,szu,szv,rku,rkv;
    node(int u,int v,int szu,int szv,int rku,int rkv):u(u),v(v),szu(szu),szv(szv),rku(rku),rkv(rkv){}
    node(){}
};
class bingchaji
{
public:
    int father[MAXN],sz[MAXN],n,rank[MAXN];
    node S[MAXN];
    int siz;
    ll c;
    void mem(int _n)
    {
        n=_n; c=0; siz=0;
        For(i,n) father[i]=i,sz[i]=1,rank[i]=1;
    }
    int getfather(int x) 
    {
        if (father[x]==x) return x;
        return getfather(father[x]);
    }
    void unite(int x,int y)
    {
        x=getfather(father[x]);
        y=getfather(father[y]);
        if (x==y) return;
        if (rank[x]>rank[y]) swap(x,y);
        S[++siz]=node(x,y,sz[x],sz[y],rank[x],rank[y]);
        c+=(ll)sz[x]*sz[y]; sz[y]+=sz[x]; sz[x]=0;
        rank[y]=max(rank[x]+1,rank[y]);
        father[x]=y;
    }
    void back(int x) {
        while(siz>x){
            node now=S[siz];
            int u=now.u,v=now.v;
            c-=(ll)now.szu*now.szv;
            father[u]=u;
            father[v]=v;
            sz[u]=now.szu; sz[v]=now.szv; rank[u]=now.rku; rank[v]=now.rkv;
            --siz;
        } 
    }
    bool same(int x,int y)
    {
        return getfather(x)==getfather(y);
    }
}S;
struct edge{
    int u,v;
    edge(int _u=0,int _v=0):u(_u),v(_v){}
};
vector<edge> edges[MAXN];
int n,m,k;
void work(int l,int r) {
    Fork(i,l,r) {
        int sz=SI(edges[i]);
        Rep(j,sz) {
            S.unite(edges[i][j].u,edges[i][j].v);
        }
    }
}

void cdq(int l,int r) {
    if (l==r) {
        printf("%lld\n",S.c);
        return;
    }
    int m=(l+r)>>1;
    int top=S.siz;
    work(m+1,r);
    cdq(l,m);
    S.back(top);
    work(l,m);
    cdq(m+1,r);
} 
int main()
{
//  freopen("F.in","r",stdin);
//  freopen(".out","w",stdout);
    while(scanf("%d%d%d",&n,&m,&k)==3) {
        S.mem(n);
        For(i,m) {
            int u=read(),v=read(),c=read();
            if (c>k) S.unite(u,v);
            else edges[c].pb(edge(u,v));
        }
        cdq(1,k);
        For(i,n) edges[i].clear();
    }   

    return 0;
}

HDU 5721 Palace

10^5个点(x,y),每次拿掉一个点,求最近公共点对距,把所有点各拿走一遍,求和。
SB题

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF ((ll)(1e20))
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long long ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ld sqr(ld a){return a*a;}
#define MAXN (100000+10)
class P{
public:
    ld x,y;
    P(){}
    P(ld x,ld y):x(x),y(y){}
    friend long double dis2(P A,P B){return sqr(A.x-B.x)+sqr(A.y-B.y);  }
    friend ll dis(P A,P B){return dis2(A,B); }
    friend bool operator<(P A,P B) {
        return A.x<B.x;
    }
}a[MAXN],a2[MAXN];
int t[MAXN]; 
int cmp(const void *x,const void *y) {
    return a[*(int*)x].y-a[*(int*)y].y;
}
ll Abs(ll a){return (a<0)?-a:a;}
pi p;
ll ans=INF;
ll bsearch(int l,int r) {
    int m=(l+r)/2;
    if (l==r) return (ll)(1e20);

    ll d=min(bsearch(l,m),bsearch(m+1,r)); 

    int k=0;
    Fork(i,l,r) {
        if (Abs(a[m].x-a[i].x)<=d) {
            t[++k]=i;
        }
    }
    qsort(t+1,k,sizeof(int),cmp);

    For(i,k) {
        Fork(j,i+1,k) {
            if (a[t[j]].y-a[t[i]].y>d) break;
            ll d2=dis(a[t[i]],a[t[j]]);
            if (d2<d) {
                d=d2;
                if (ans>d2) ans=d2,p=mp(t[i],t[j]);
            }
        }
    }
    return d;
} 
int main()
{
//  freopen("G.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    while(T--) {
        int n=read();
        For(i,n) a[i].x=read(),a[i].y=read();

        sort(a+1,a+1+n); ans=INF;
        ll dis=bsearch(1,n);

        dis*=(ll)n-2;
        memcpy(a2,a,sizeof(a));
        int t=p.se;
        swap(a[p.fi],a[n]);
        sort(a+1,a+n);
        dis+=bsearch(1,n-1);

        memcpy(a,a2,sizeof(a));
        swap(a[t],a[n]);
        sort(a+1,a+n);
        dis+=bsearch(1,n-1);
        cout<<dis<<endl;
    }   

    return 0;
}

HDU 5755 Gambler Bo

给一个30*30的矩阵,求电灯开关问题的一个合法解
高斯消元
容易证明复杂度是O(N^2h)=O(n^5)的

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (3)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 

#define MAXN (900+10)
typedef int Matrix[MAXN][MAXN];
void gauss_elimination(Matrix A, int n) { //假设系数矩阵A可逆 A[0..n-1,0..n]
//运行结束后A[i][i]极为第i个变量的值 
    Rep(i,n) {
        int r=i;
        Fork(j,i+1,n-1) {
            if (fabs(A[j][i])>fabs(A[r][i])) r=j;
        }   
        if (r>i) {
            Rep(j,n+1) swap(A[r][j],A[i][j]);
        }
        Fork(k,i+1,n-1) {
            while(A[k][i])
                ForkD(j,i,n) {A[k][j] += A[i][j]; A[k][j]%=3; }
        }
    }
    RepD(i,n-1) {
        Fork(j,i+1,n-1) A[i][n] -= A[j][n] * A[i][j];
        A[i][n] *= A[i][i];
        A[i][n]=sub(A[i][n],0);
    }
}

Matrix A;
int a[MAXN][MAXN],n,m;
int id(int i,int j){return i*m+j;} 
bool inside(int i,int j){return 0<=i&&i<n&&0<=j&&j<m; }
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int main()
{
//  freopen("H.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    while(T--) {
        MEM(A)
        n=read(),m=read();
        Rep(i,n) Rep(j,m) {
            a[i][j] = read();
        }
        Rep(i,n) Rep(j,m) {
            int id1=id(i,j);
            Rep(d,4) {
                int x=i+dir[d][0],y=j+dir[d][1];
                if (!inside(x,y)) continue;
                int id2=id(x,y);
                A[id1][id2]=1;
            }
            A[id1][id1]=2;
            A[id1][n*m]=(3-a[i][j])%3;
        }
        gauss_elimination(A,n*m);
        vector<pi> v;
        Rep(i,n*m) Rep(j,A[i][n*m]) v.pb(mp(i/m+1,i%m+1));
        cout<<SI(v)<<endl;
        Rep(i,SI(v)) printf("%d %d\n",v[i].fi,v[i].se);
        cout<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值