Codeforces Round #Pi (Div. 2)(最短路重建图+tarjan重边找桥)

C. Geometric Progression

Polycarp loves geometric progressions very much. Since he was only three years old, he loves only the progressions of length three. He also has a favorite integer k and a sequence a, consisting of n integers.

He wants to know how many subsequences of length three can be selected from a, so that they form a geometric progression with common ratio k.

A subsequence of length three is a combination of three such indexes i1, i2, i3, that 1 ≤ i1 < i2 < i3 ≤ n. That is, a subsequence of length three are such groups of three elements that are not necessarily consecutive in the sequence, but their indexes are strictly increasing.

A geometric progression with common ratio k is a sequence of numbers of the form b·k0, b·k1, …, b·kr - 1.

Polycarp is only three years old, so he can not calculate this number himself. Help him to do it.

Input

The first line of the input contains two integers, n and k (1 ≤ n, k ≤ 2·105), showing how many numbers Polycarp’s sequence has and his favorite number.

The second line contains n integers a1, a2, …, an ( - 109 ≤ ai ≤ 109) — elements of the sequence.

Output

Output a single number — the number of ways to choose a subsequence of length three, such that it forms a geometric progression with a common ratio k.
Sample test(s)
Input

5 2
1 1 2 2 4

Output

4

Input

3 1
1 1 1

Output

1

Input

10 3
1 2 6 2 3 6 9 18 3 9

Output

6

Note

In the first sample test the answer is four, as any of the two 1s can be chosen as the first element, the second element can be any of the 2s, and the third element of the subsequence must be equal to 4.

题意:有多少个(a,b,c)组合,满足下表递增,并且他们之间有倍数关系
思路:枚举 每个数作为中间数,然后看两遍有多少个满足条件的,用map记录一下就行了

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=200010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int N,K,a[maxn],cntl[maxn],cntr[maxn];
map<LL,int> mp;
int main()
{
    scanf("%d%d",&N,&K);
    for(int i=1;i<=N;i++)scanf("%d",&a[i]);
    for(int i=1;i<=N;i++)
    {
        if(a[i]%K)
        {
            mp[a[i]]++;
            continue;
        }
        LL x=a[i]/K;
        cntl[i]=mp[x];
        mp[a[i]]++;
    }
    mp.clear();
    for(int i=N;i>=1;i--)
    {
        LL x=1LL*a[i]*K;
        cntr[i]=mp[x];
        mp[a[i]]++;
    }

    LL ans=0;
    for(int i=1;i<=N;i++)
        ans+=1LL*cntl[i]*cntr[i];
    cout<<ans<<endl;
    return 0;
}

D. One-Dimensional Battle Ships

Alice and Bob love playing one-dimensional battle ships. They play on the field in the form of a line consisting of n square cells (that is, on a 1 × n table).

At the beginning of the game Alice puts k ships on the field without telling their positions to Bob. Each ship looks as a 1 × a rectangle (that is, it occupies a sequence of a consecutive squares of the field). The ships cannot intersect and even touch each other.

After that Bob makes a sequence of “shots”. He names cells of the field and Alice either says that the cell is empty (“miss”), or that the cell belongs to some ship (“hit”).

But here’s the problem! Alice like to cheat. May be that is why she responds to each Bob’s move with a “miss”.

Help Bob catch Alice cheating — find Bob’s first move, such that after it you can be sure that Alice cheated.

Input

The first line of the input contains three integers: n, k and a (1 ≤ n, k, a ≤ 2·105) — the size of the field, the number of the ships and the size of each ship. It is guaranteed that the n, k and a are such that you can put k ships of size a on the field, so that no two ships intersect or touch each other.

The second line contains integer m (1 ≤ m ≤ n) — the number of Bob’s moves.

The third line contains m distinct integers x1, x2, …, xm, where xi is the number of the cell where Bob made the i-th shot. The cells are numbered from left to right from 1 to n.

Output

Print a single integer — the number of such Bob’s first move, after which you can be sure that Alice lied. Bob’s moves are numbered from 1 to m in the order the were made. If the sought move doesn’t exist, then print “-1”.
Sample test(s)
Input

11 3 3
5
4 8 6 1 11

Output

3

Input

5 1 3
2
1 5

Output

-1

Input

5 1 3
1
3

Output

1

保存一个当前剩余的格子能安排下多少ship,如果个数小于K个,那么说明不满足了

#include<bits/stdc++.h>
using namespace std;
int N,K,A,M;
set<int> sp;
int main()
{
    scanf("%d%d%d",&N,&K,&A);
    scanf("%d",&M);
    bool flag=true;
    int ans=0;
    sp.insert(0);
    int cnt=(N+1)/(A+1);
    for(int i=1;i<=M;i++)
    {
        int x;
        scanf("%d",&x);
        if(!flag)continue;
        if(sp.empty()){sp.insert(x);continue;}
        auto pos=sp.lower_bound(x);
        if(pos==sp.end())
        {
            cnt-=(N-*sp.rbegin()+1)/(A+1);
            cnt+=(N-x+1)/(A+1);
            cnt+=(x-*sp.rbegin())/(A+1);
        }
        else
        {
            auto l=pos;pos--;
            cnt-=(*l-*pos)/(A+1);
            cnt+=(x-*pos)/(A+1);
            cnt+=(*l-x)/(A+1);
        }
        if(cnt<K){flag=false;ans=i;}
        sp.insert(x);
    }
    if(!flag)printf("%d\n",ans);
    else printf("-1\n");
    return 0;
}

E. President and Roads

Berland has n cities, the capital is located in city s, and the historic home town of the President is in city t (s ≠ t). The cities are connected by one-way roads, the travel time for each of the road is a positive integer.

Once a year the President visited his historic home town t, for which his motorcade passes along some path from s to t (he always returns on a personal plane). Since the president is a very busy man, he always chooses the path from s to t, along which he will travel the fastest.

The ministry of Roads and Railways wants to learn for each of the road: whether the President will definitely pass through it during his travels, and if not, whether it is possible to repair it so that it would definitely be included in the shortest path from the capital to the historic home town of the President. Obviously, the road can not be repaired so that the travel time on it was less than one. The ministry of Berland, like any other, is interested in maintaining the budget, so it wants to know the minimum cost of repairing the road. Also, it is very fond of accuracy, so it repairs the roads so that the travel time on them is always a positive integer.

Input

The first lines contain four integers n, m, s and t (2 ≤ n ≤ 105; 1 ≤ m ≤ 105; 1 ≤ s, t ≤ n) — the number of cities and roads in Berland, the numbers of the capital and of the Presidents’ home town (s ≠ t).

Next m lines contain the roads. Each road is given as a group of three integers ai, bi, li (1 ≤ ai, bi ≤ n; ai ≠ bi; 1 ≤ li ≤ 106) — the cities that are connected by the i-th road and the time needed to ride along it. The road is directed from city ai to city bi.

The cities are numbered from 1 to n. Each pair of cities can have multiple roads between them. It is guaranteed that there is a path from s to t along the roads.

Output

Print m lines. The i-th line should contain information about the i-th road (the roads are numbered in the order of appearance in the input).

If the president will definitely ride along it during his travels, the line must contain a single word “YES” (without the quotes).

Otherwise, if the i-th road can be repaired so that the travel time on it remains positive and then president will definitely ride along it, print space-separated word “CAN” (without the quotes), and the minimum cost of repairing.

If we can’t make the road be such that president will definitely ride along it, print “NO” (without the quotes).
Sample test(s)
Input

6 7 1 6
1 2 2
1 3 10
2 3 7
2 4 8
3 5 3
4 5 2
5 6 1

Output

YES
CAN 2
CAN 1
CAN 1
CAN 1
CAN 1
YES

Input

3 3 1 3
1 2 10
2 3 10
1 3 100

Output

YES
YES
CAN 81

Input

2 2 1 2
1 2 1
1 2 2

Output

YES
NO

Note

The cost of repairing the road is the difference between the time needed to ride along it before and after the repairing.

In the first sample president initially may choose one of the two following ways for a ride: 1 → 2 → 4 → 5 → 6 or 1 → 2 → 3 → 5 → 6.
题意:国王每次只走最短路,问哪些路是必经的,如果不是,那么最少修改多少权值,能让他成为必经的,或者根本不可能
思路:首先求一边最短路,然后对最短路建图,然后tarjan找桥

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=200010;
const int maxm=1010;
const int MOD=1e9+7;
const LL INF=1e18;
int N,M,S,T;
int ans[maxn];
struct Edge
{
    int from,to,id;
    LL dist;
    Edge(int f=0,int t=0,LL d=0,int _id=0):from(f),to(t),dist(d),id(_id){}
};
Edge edge[maxn];
struct HeapNode//优先队列节点
{
    int u;
    LL d;
    HeapNode(LL _d=0,int _u=0):d(_d),u(_u){}
    bool operator<(const HeapNode &rhs)const
    {
        return d>rhs.d;
    }
};
struct Dijkstra
{
    int n,m;               //点数和边数
    vector<Edge> edges;    //边列表
    vector<int> G[maxn];   //每个节点出发的边编号(编号从0开始)
    bool done[maxn];       //是否已永久标号
    LL d[maxn];           //s到各个点的距离
    vector<int> p[maxn];           //最短路中的上一条边
    void init(int n)
    {
        this->n=n;
        for(int i=0;i<=n;i++)G[i].clear(),p[i].clear();
        edges.clear();
    }
    void AddEdge(int from,int to,int dist,int id)
    {
        edges.push_back(Edge(from,to,dist,id));
        m=edges.size();
        G[from].push_back(m-1);
    }
    void dijkstra(int s)
    {
        priority_queue<HeapNode> Q;
        for(int i=0;i<=n;i++)d[i]=INF;
        d[s]=0;
        memset(done,0,sizeof(done));
        Q.push(HeapNode(0,s));
        while(!Q.empty())
        {
            HeapNode x=Q.top();Q.pop();
            int u=x.u;
            if(done[u])continue;
            done[u]=true;
            for(int 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;
                    p[e.to].clear();
                    p[e.to].push_back(G[u][i]);
                    Q.push(HeapNode(d[e.to],e.to));
                }
            }
        }
    }

}dij1,dij2;
int dfs_clock,cnt;
int dfn[maxn],low[maxn];
vector<Edge> g[maxn];
bool vis[maxn];
int tarjan(int u,int fa)
{
    int lowu=dfn[u]=++dfs_clock;
    int child=0;
    int len=g[u].size();
    for(int i=0;i<len;i++)
    {
        Edge e=g[u][i];
        int v=e.to;
        if(!dfn[v])
        {
            child++;
            int lowv=tarjan(v,e.id);//有重边要传递边的编号
            lowu=min(lowv,lowu);
            if(lowv>dfn[u])
                ans[e.id]=true;
        }
        else if(dfn[v]<dfn[u]&&e.id!=fa)
            lowu=min(lowu,dfn[v]);
    }
    low[u]=lowu;
    return lowu;
}
void build()
{
    for(int i=0;i<M;i++)
    {
        int u=dij1.edges[i].from;
        int v=dij1.edges[i].to;
        int w=dij1.edges[i].dist;
        if(dij1.d[u]+w==dij1.d[v]&&dij2.d[v]+w==dij2.d[u])
        {
            g[u].push_back(Edge(u,v,w,dij1.edges[i].id));
            g[v].push_back(Edge(v,u,w,dij1.edges[i].id));
        }
    }
}
int main()
{
    scanf("%d%d%d%d",&N,&M,&S,&T);
    int u,v,len;
    dij1.init(N);
    dij2.init(N);
    for(int i=0;i<M;i++)
    {
        scanf("%d%d%d",&u,&v,&len);
        dij1.AddEdge(u,v,len,i);
        dij2.AddEdge(v,u,len,i);
    }
    dij1.dijkstra(S);
    dij2.dijkstra(T);
    if(dij1.d[T]==INF)
    {
        for(int i=0;i<M;i++)
            printf("NO\n");
        return 0;
    }
    memset(ans,0,sizeof(ans));
    dfs_clock=cnt=0;
    memset(dfn,0,sizeof(dfn));
    build();
    tarjan(S,-1);
    for(int i=0;i<M;i++)
    {
        if(ans[i])
        {
            printf("YES\n");
            continue;
        }
        Edge e=dij1.edges[i];
        int u=e.from,v=e.to;
        LL tmp=dij1.d[u]+dij2.d[v]+e.dist-dij1.d[T]+1;
        if(tmp>=e.dist)printf("NO\n");
        else printf("CAN %I64d\n",tmp);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值