HDU多校一

1001: 

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=400010;
const int Mod=998244353;
struct in{
    int L,R,P;
    bool friend operator <(in w,in v){
        if(w.R!=v.R) return w.R<v.R;
        if(w.L!=v.L) return w.L<v.L;
        return w.P<v.P;
    }
}s[maxn];
int dp[maxn],q[maxn],tot;
int a[maxn],b[maxn],C[110][110],kkkk,pp[110][100];
void get()
{
    rep(i,0,100) C[i][0]=1;
    rep(i,1,100) rep(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%Mod;
    pp[0][0]=1;
    for(int i=1;i<=100;i++)
     for(int j=1;j<=min(i,4);j++){
       pp[i][j]=(1LL*pp[i-1][j]*j%Mod+1LL*pp[i-1][j-1]*j%Mod)%Mod;
    }
}
int qpow(int a,int x)
{
    int res=1; while(x){
        if(x&1) res=1LL*res*a%Mod;
        x>>=1; a=1LL*a*a%Mod;
    }
    return res;
}
int solve()
{
    kkkk=1;
    a[1]=s[q[tot]].R-s[q[tot]].L+1,b[1]=s[q[tot]].P;
    for(int i=tot;i>=2;i--){
        kkkk++;
        a[kkkk]=s[q[i]].L-s[q[i-1]].L;
        b[kkkk]=s[q[i-1]].P;
    }
    int res=1;
    for(int i=1;i<=tot;i++){
        if(a[i]<b[i]-b[i-1]) return 0;
        res=1LL*res*pp[a[i]][b[i]-b[i-1]]%Mod*C[4][b[i]-b[i-1]]%Mod;
    }
    return res;
}
int main()
{
    int T,N,M;
    get();
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        rep(i,1,M) scanf("%d%d%d",&s[i].L,&s[i].R,&s[i].P);
        sort(s+1,s+M+1);
        dp[0]=1; int kkk=1;
        for(int i=1,j=0;i<=N;i++){
            int t=j;
            while(j+1<=M&&s[j+1].R<=i) j++;
            tot=0;
            for(int k=t+1;k<=j;k++) {
                if(tot>0&&s[k].P>s[q[tot]].P) kkk=-1;
                if(tot>0&&s[k].P>=s[q[tot]].P) continue;
                q[++tot]=k;
            }
            int pre=i-1,res=4;
            if(tot){
                pre=s[q[1]].L-1;
                res=solve();
            }
            dp[i]=1LL*dp[pre]*res%Mod;
        }
        if(kkk==-1) dp[N]=0;
        printf("%d\n",dp[N]);
    }
    return 0;
}
View Code

1002:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1000010;
int p[maxn][31],pos[maxn][31];
int ans;
void add(int i,int x)
{
    rep(j,0,30) p[i][j]=p[i-1][j],pos[i][j]=pos[i-1][j];
    int ti=i;
    rep2(j,30,0){
        if(x&(1<<j)){
            if(!p[i][j]) { p[i][j]=x; pos[i][j]=ti; break; }
            if(pos[i][j]<ti) swap(p[i][j],x),swap(pos[i][j],ti);
            x^=p[i][j];
        }
    }
}
int query(int L,int R)
{
     ans=0;
     rep2(j,30,0) if(pos[R][j]>=L&&(ans^p[R][j])>ans) ans^=p[R][j];
     printf("%d\n",ans);
}
int main()
{
    int T,N,Q,x,L,R,opt;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&Q); ans=0;
        rep(i,1,N+Q) rep(j,0,30) p[i][j]=pos[i][j]=0;
        rep(i,1,N) scanf("%d",&x),add(i,x);
        while(Q--){
            scanf("%d",&opt);
            if(opt==0) {
                scanf("%d%d",&L,&R);
                L=(L^ans)%N+1; R=(R^ans)%N+1;
                if(L>R) swap(L,R);
                //cout<<L<<" "<<R<<endl;
                query(L,R);
            }
            else {
                scanf("%d",&x);
                x^=ans;
                add(++N,x);
            }
        }
    }
    return 0;
}
View Code

1004:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 2e5 + 10;
const ll INF = 1e18 + 7;
ll l[maxn], s[maxn], v[maxn];
int n;
bool judge(double ans)
{
    double dis = v[n] * ans - s[n];
    if(dis < 0)return false;
    for(int i = n - 1; i >= 0; i--)
    {
        double tmp = v[i] * ans - s[i];
        if(tmp + l[i + 1] > dis)
            dis = dis - l[i + 1];
        else dis = tmp;
        if(dis < 0)return false;
    }
    return true;
}
int main()
{
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 0; i <= n; i++)scanf("%lld", &l[i]);
        for(int i = 0; i <= n; i++)scanf("%lld", &s[i]);
        for(int i = 0; i <= n; i++)scanf("%lld", &v[i]);
        double l = 0, r = 1e10, ans = 0;
        while(abs(r - l) >= 1e-10)
        {
            double mid = (l + r) / 2;
            if(judge(mid))ans = mid, r = mid;
            else l = mid;
        }
        printf("%.10f\n", ans);
    }
    return 0;
}
View Code

1005:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e4 + 10;
const ll INF = 1e18 + 7;
struct Edge
{
    ll from, to, dist;
    Edge(ll u, ll v, ll d):from(u), to(v), dist(d){}
    Edge(){}
};
struct Heapnode
{
    ll d, u;//d为距离,u为起点
    Heapnode(){}
    Heapnode(ll d, ll u):d(d), u(u){}
    bool operator <(const Heapnode & a)const
    {
        return d > a.d;//这样优先队列先取出d小的
    }
};
struct Dijkstra
{
    ll n, m;
    vector<Edge>edges;//存边的信息
    vector<ll>G[maxn];//G[i]表示起点为i的边的序号集
    bool v[maxn];//标记点是否加入集合
    ll d[maxn];//起点s到各个点的最短路
    Dijkstra(){}
    void init(ll n)
    {
        this -> n = n;
        for(ll i = 0; i <= n; i++)G[i].clear();
        edges.clear();
    }
    void addedge(ll from, ll to, ll dist)
    {
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        G[from].push_back(m - 1);//存以from为起点的下一条边
    }
    void dijkstra(ll s)//以s为起点
    {
        priority_queue<Heapnode>q;
        for(ll i = 0; i <= n; i++)d[i] = 1e18;
        d[s] = 0;
        memset(v, 0, sizeof(v));
        q.push(Heapnode(0, s));
        while(!q.empty())
        {
            Heapnode now = q.top();
            q.pop();
            ll u = now.u;//当前起点
            if(v[u])continue;//如果已经加入集合,continue
            v[u] = 1;
            for(ll i = 0; i < G[u].size(); i++)
            {
                Edge& e = edges[G[u][i]];//引用节省代码
                if(d[e.to] > d[u] + e.dist)
                {
                    d[e.to] = d[u] + e.dist;
                    q.push(Heapnode(d[e.to], e.to));
                }
            }
        }
    }
};
Dijkstra ans;

struct edge
{
    ll u, v, c, f;
    edge(ll u, ll v, ll c, ll f):u(u), v(v), c(c), f(f){}
};
vector<edge>e;
vector<ll>G[maxn];
ll level[maxn];//BFS分层,表示每个点的层数
ll iter[maxn];//当前弧优化
ll m;
void init(ll n)
{
    for(ll i = 0; i <= n; i++)G[i].clear();
    e.clear();
}
void addedge(ll u, ll v, ll c)
{
    e.push_back(edge(u, v, c, 0));
    e.push_back(edge(v, u, 0, 0));
    m = e.size();
    G[u].push_back(m - 2);
    G[v].push_back(m - 1);
}
void BFS(ll s)//预处理出level数组
//直接BFS到每个点
{
    memset(level, -1, sizeof(level));
    queue<ll>q;
    level[s] = 0;
    q.push(s);
    while(!q.empty())
    {
        ll u = q.front();
        q.pop();
        for(ll v = 0; v < G[u].size(); v++)
        {
            edge& now = e[G[u][v]];
            if(now.c > now.f && level[now.v] < 0)
            {
                level[now.v] = level[u] + 1;
                q.push(now.v);
            }
        }
    }
}
ll dfs(ll u, ll t, ll f)//DFS寻找增广路
{
    if(u == t)return f;//已经到达源点,返回流量f
    for(ll &v = iter[u]; v < G[u].size(); v++)
        //这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
        //在每次找增广路的时候,数组要清空
    {
        edge &now = e[G[u][v]];
        if(now.c - now.f > 0 && level[u] < level[now.v])
            //now.c - now.f > 0表示这条路还未满
            //level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
        {
            ll d = dfs(now.v, t, min(f, now.c - now.f));
            if(d > 0)
            {
                now.f += d;//正向边流量加d
                e[G[u][v] ^ 1].f -= d;
    //反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
                return d;
            }
        }
    }
    return 0;
}
ll Maxflow(ll s, ll t)
{
    ll flow = 0;
    for(;;)
    {
        BFS(s);
        if(level[t] < 0)return flow;//残余网络中到达不了t,增广路不存在
        memset(iter, 0, sizeof(iter));//清空当前弧数组
        ll f;//记录增广路的可增加的流量
        while((f = dfs(s, t, INF)) > 0)
        {
            flow += f;
        }
    }
    return flow;
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        ll n, m;
        scanf("%lld%lld", &n, &m);
        ans.init(n);
        for(ll i = 1; i <= m; i++)
        {
            ll u, v ,w;
            scanf("%lld%lld%lld", &u, &v, &w);
            ans.addedge(u, v, w);
        }
        ans.dijkstra(1);
        if(ans.d[n] >= 1e18)
        {
            puts("0");
            continue;
        }
        init(n);
        for(auto tmp : ans.edges)
        {
            ll u = tmp.from, v = tmp.to, w = tmp.dist;
            if(ans.d[u] + w == ans.d[v])
                addedge(u, v, w);
        }
        printf("%lld\n", Maxflow(1, n));
    }
    return 0;
}
View Code

1009:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
char s[100010],ans[100010];
int n,K,nex[100010][26],L,R,cnt,sum[100010][26],l[26],r[26],nextt[26];
bool flag;
template<class T>
inline void read(T&a){
    char c=getchar();
    for(a=0;(c<'0'||c>'9')&&c!='-';c=getchar());
    bool f=0;if(c=='-')f=1,c=getchar();
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
    if(f)a=-a;
}
int main(){
    while(~scanf("%s",s+1)){
        read(K);L=R=cnt=0;n=strlen(s+1);
        for(register int i=0;i<26;i++)read(l[i]),read(r[i]),L+=l[i],R+=r[i],nextt[i]=n+1;
        if(K<L||K>R){puts("-1");continue;}
        memset(sum[n+1],0,sizeof(sum[n+1]));
        for(register int i=n;i;i--){
            memcpy(sum[i],sum[i+1],sizeof(sum[i]));
            sum[i][s[i]-'a']++;memcpy(nex[i],nextt,sizeof(nextt));
            nextt[s[i]-'a']=i;
        }
        memcpy(nex[0],nextt,sizeof(nextt));flag=1;
        memcpy(sum[0],sum[1],sizeof(sum[0]));R=0;
        for(register int i=0;i<26;i++){
            if(sum[0][i]<l[i]){puts("-1");flag=0;break;}
            R+=min(sum[0][i],r[i]);
        }
        if(K>R){puts("-1");continue;}
        if(flag){
            for(register int i=0,j;i<=n;i=j){
                bool fl=1;
                for(register int k=0;k<26;k++)
                    if(nex[i][k]<=n&&r[k]&&(l[k]||K-L>0)){
                        fl=0;bool f=1;R=0;
                        for(register int p=0;p<26;p++){
                            if(sum[nex[i][k]][p]<l[p]){f=0;break;}
                            R+=min(sum[nex[i][k]][p],r[p]);
                        }
                        if(K>R)f=0;
                        if(f){
                            r[k]--;K--;flag=0; 
                            ans[++cnt]='a'+k;
                            if(l[k])l[k]--,L--;
                            j=nex[i][k];break;
                        }
                    }
                if(fl)j=n+1;
            }
            ans[cnt+1]=0;
            if(flag||K)puts("-1");
            else puts(ans+1);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/11227138.html