Codeforces Round #532 (Div. 2) 解题报告

Codeforces Round #532 (Div. 2)

A. Roman and Browser

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
This morning, Roman woke up and opened the browser with n opened tabs numbered from 1 to n. There are two kinds of tabs: those with the information required for the test and those with social network sites. Roman decided that there are too many tabs open so he wants to close some of them.

He decided to accomplish this by closing every k-th (2≤k≤n−1) tab. Only then he will decide whether he wants to study for the test or to chat on the social networks. Formally, Roman will choose one tab (let its number be b) and then close all tabs with numbers c=b+i⋅k that satisfy the following condition: 1≤c≤n and i is an integer (it may be positive, negative or zero).

For example, if k=3, n=14 and Roman chooses b=8, then he will close tabs with numbers 2, 5, 8, 11 and 14.

After closing the tabs Roman will calculate the amount of remaining tabs with the information for the test (let's denote it e) and the amount of remaining social network tabs (s). Help Roman to calculate the maximal absolute value of the difference of those values |e−s| so that it would be easy to decide what to do next.

Input
The first line contains two integers n and k (2≤k
26 13
26 14
26 15
26 16

1 700 800

2 1 2

<...>

-1 -1 -1
outputCopy











999 998

999 997

<...>

999 26
Note
The example is trimmed. The full initial positions of the rooks in the first test are available at https://pastebin.com/qQCTXgKP. It is not guaranteed that they will behave as in the example.

-----------------------------------------------------------------------------------------
E. Andrew and Taxi

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Andrew prefers taxi to other means of transport, but recently most taxi drivers have been acting inappropriately. In order to earn more money, taxi drivers started to drive in circles. Roads in Andrew's city are one-way, and people are not necessary able to travel from one part to another, but it pales in comparison to insidious taxi drivers.

The mayor of the city decided to change the direction of certain roads so that the taxi drivers wouldn't be able to increase the cost of the trip endlessly. More formally, if the taxi driver is on a certain crossroads, they wouldn't be able to reach it again if he performs a nonzero trip.

Traffic controllers are needed in order to change the direction the road goes. For every road it is known how many traffic controllers are needed to change the direction of the road to the opposite one. It is allowed to change the directions of roads one by one, meaning that each traffic controller can participate in reversing two or more roads.

You need to calculate the minimum number of traffic controllers that you need to hire to perform the task and the list of the roads that need to be reversed.

Input
The first line contains two integers n and m (2≤n≤100000, 1≤m≤100000) — the number of crossroads and the number of roads in the city, respectively.

Each of the following m lines contain three integers ui, vi and ci (1≤ui,vi≤n, 1≤ci≤109, ui≠vi) — the crossroads the road starts at, the crossroads the road ends at and the number of traffic controllers required to reverse this road.

Output
In the first line output two integers the minimal amount of traffic controllers required to complete the task and amount of roads k which should be reversed. k should not be minimized.

In the next line output k integers separated by spaces — numbers of roads, the directions of which should be reversed. The roads are numerated from 1 in the order they are written in the input. If there are many solutions, print any of them.

Examples
inputCopy
5 6
2 1 1
5 2 6
2 3 2
3 4 3
4 5 5
1 5 4
outputCopy
2 2
1 3 
inputCopy
5 7
2 1 5
3 2 3
1 3 3
2 4 1
4 3 5
5 4 1
1 5 3
outputCopy
3 3
3 4 7 
Note
There are two simple cycles in the first example: 1→5→2→1 and 2→3→4→5→2. One traffic controller can only reverse the road 2→1 and he can't destroy the second cycle by himself. Two traffic controllers can reverse roads 2→1 and 2→3 which would satisfy the condition.

In the second example one traffic controller can't destroy the cycle 1→3→2→1. With the help of three controllers we can, for example, reverse roads 1→3 ,2→4, 1→5.

-----------------------------------------------------------------------------------------
F. Ivan and Burgers

time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Ivan loves burgers and spending money. There are n burger joints on the street where Ivan lives. Ivan has q friends, and the i-th friend suggested to meet at the joint li and walk to the joint ri (li≤ri). While strolling with the i-th friend Ivan can visit all joints x which satisfy li≤x≤ri.

For each joint Ivan knows the cost of the most expensive burger in it, it costs ci burles. Ivan wants to visit some subset of joints on his way, in each of them he will buy the most expensive burger and spend the most money. But there is a small issue: his card broke and instead of charging him for purchases, the amount of money on it changes as follows.

If Ivan had d burles before the purchase and he spent c burles at the joint, then after the purchase he would have d⊕c burles, where ⊕ denotes the bitwise XOR operation.

Currently Ivan has 22100−1 burles and he wants to go out for a walk. Help him to determine the maximal amount of burles he can spend if he goes for a walk with the friend i. The amount of burles he spends is defined as the difference between the initial amount on his account and the final account.

Input
The first line contains one integer n (1≤n≤500000) — the number of burger shops.

The next line contains n integers c1,c2,…,cn (0≤ci≤106), where ci — the cost of the most expensive burger in the burger joint i.

The third line contains one integer q (1≤q≤500000) — the number of Ivan's friends.

Each of the next q lines contain two integers li and ri (1≤li≤ri≤n) — pairs of numbers of burger shops between which Ivan will walk.

Output
Output q lines, i-th of which containing the maximum amount of money Ivan can spend with the friend i.

Examples
inputCopy
4
7 2 3 4
3
1 4
2 3
1 3
outputCopy
7
3
7
inputCopy
5
12 14 23 13 7
15
1 1
1 2
1 3
1 4
1 5
2 2
2 3
2 4
2 5
3 3
3 4
3 5
4 4
4 5
5 5
outputCopy
12
14
27
27
31
14
25
26
30
23
26
29
13
13
7
Note
In the first test, in order to spend the maximum amount of money with the first and third friends, Ivan just needs to go into the first burger. With a second friend, Ivan just go to the third burger.

In the second test for a third friend (who is going to walk from the first to the third burger), there are only 8 options to spend money — 0, 12, 14, 23, 12⊕14=2, 14⊕23=25, 12⊕23=27, 12⊕14⊕23=20. The maximum amount of money it turns out to spend, if you go to the first and third burger — 12⊕23=27.

题意描述:

A. 去掉一个等差序列,问你剩下的1和-1的差值的和

//A

#include
using namespace std;
int main()
{
    int n,k,ans,flag,temp,countt;
    int a[100010],c[100010];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        ans=0;
        flag=1;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);

        for(int i=0;i<=k;i++)
        {
            memset(c,0,sizeof(c));
            for(int j=i;j<=n;j+=k)
                c[j]=1;
            temp=0;
            countt=0;
            for(int j=1;j<=n;j++)
            if(!c[j]&&a[j]==1)
                temp++;
            else
                if(!c[j])
                   countt++;
            ans=max(ans,abs(temp-countt));
        }
        printf("%d\n",ans);
    }
    return 0;
}

B.给定一个k值和n个数,如果k个数已经全出现过一次了,就输出1,这是一个循环,然后全置为0

                                       如果没有,就输出0

#include
using namespace std;
int a[2000010],c[2000010],b[2000010];
char d[2000010];
int main()
{
    int k,n,ans,flag,tmp;
    scanf("%d%d",&k,&n);
    {
        ans=0;
        flag=1;
        memset(c,0,sizeof(c));
        memset(b,0,sizeof(b));
        for(int i=0;i

C. 给你中间一个圆的半径和它被n个等半径的圆(与前面圆的半径关系不一定)所完全包围,问你外面圆的半径是多少。

 

R/( R+ r)= sin(1/n*π)  因为外面圆都是相切的,所以能构造出一个直角三角形来,出来上面的式子

#include
using namespace std;
#define pi 3.1415926535893238
double x,y,a,b;
int main()
{
  scanf("%lf%lf",&x,&y);
  a=sin(1.0/x*pi);
  b=y*a/(1.0-a);
  printf("%.7f\n",b);
  return 0;
}

D.

白:八连通一次一格;
黑:瞬间移动
要求任意棋子移动不能移动到有棋子的格子上
要求白走到黑的同行或者同列,白胜
我们扮演白,黑不会瞬间移动到我们的同行同列上

棋盘:999*999
黑666个
666/4=166…2;
所以平均下来将棋盘平均分四块
在平均分的这种最差的情况下
其中三块黑棋数量和最多有167+167+166=500;
所以先将白走到500,500也就是棋盘中央
然后往黑旗数量最少的那块的反对角线走即可必胜.
自己画画图,将黑的同行同列画出就是有点像扫描线一样扫.
其实是扫四分之三的区域

#include
using namespace std;typedef long long ll;typedef pairpii;
#define fi first
#define sc second
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;ix1&&mp[x-1][y]==0) x--;
		cout << x << ' ' << y << endl;
		cin >> now >> x2 >> y2;
		if(now<0) exit(0);
		mp[xx[now]][yy[now]]=0;
		xx[now]=x2;yy[now]=y2;
		mp[x2][y2]=1;
	}
}
int main() {
	cin >> x >> y;
	ff(i,1,666) {cin >> xx[i] >> yy[i];mp[xx[i]][yy[i]]=1;}
	tosw(m,m);
	ff(i,0,3) hh[i].w=i;
	ff(i,1,999) ff(j,1,999) if(mp[i][j]) {
		if(im) hh[1].num++;
		else if(i>m&&j

E.

题意
给你一个图1-n标号,m条有向边。
每条有向边有一个权值,代表翻转其方向所需代价。
求使得图变成无环图,翻转边权的最大值最小。

思路
二分答案,判断权值大于答案的边集是否能成环,如果不能说明答案可以再小点,否则答案可以大点。
关键是翻转哪些边比较难想,第一次感受到拓扑排序,排序二字用处。
按拓扑排序的顺序,给每个点从小到大赋权,最后判断如果起点权值大于终点权值则需要翻转。

#include 
using namespace std;

int n, m;
int sum, in[100005], top[100005];
vector  e[100005], path;

struct Node
{
    int u, v, w;
}data[100005];

int f(int mid)
{
    sum = 0;
    for(int i = 1; i <= n; ++i) e[i].clear();
    memset(in,0,sizeof(in));
    for(int i = 1; i <= m; ++i)
    {
        if(data[i].w > mid)
        {
            e[data[i].u].push_back(data[i].v);
            ++in[data[i].v];
        }
    }
    queue q;
    for(int i = 1; i <= n; ++i) if(!in[i]) q.push(i), top[i] = ++sum;

    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(auto v : e[u])
        {
            --in[v];
            if(!in[v]) q.push(v), top[v] = ++sum;
        }
    }

    for(int i = 1; i <= n; ++i) if(in[i]) return 0;
    return 1;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= m; ++i) scanf("%d%d%d",&data[i].u,&data[i].v,&data[i].w);
    int l = 0, r = 1e9, mid, ans;
    while(l <= r)
    {
        mid = (l+r) >> 1;
        if(f(mid)) r = mid-1, ans = mid;
        else l = mid+1;
    }
    f(ans); 
    // 每个点top都有值,且必定能够通过翻转某些边得到当前top值
    for(int i = 1; i <= m; ++i) if(data[i].w <= ans && top[data[i].u] > top[data[i].v]) path.push_back(i);

    printf("%d %d\n",ans,path.size());
    for(auto i : path) printf("%d ",i);
    return 0;
}

F.

给定N个数,Q次询问,求区间最大异或和。

我们考虑离线,把所有询问按右端点排序,然后从左到有处理询问,对于当前询问[L,R];我们把[1,R]所有的数加入线性基,关键是对于每一位,我们保留其为位置,这里肯定是贪心地保留越后面的位置越优。 那么查询的时候,如果一个线性基里的数位置>=L,则可以考虑更新答案。

#include
#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=500010;
struct in{
    int l,r,id;
    friend bool operator< (in w,in v){ return w.r=id&&(res^p[i])>res) res^=p[i];
    return res;
}
int main()
{
    scanf("%d",&N);
    rep(i,1,N) scanf("%d",&a[i]);
    scanf("%d",&Q);
    rep(i,1,Q) scanf("%d%d",&s[i].l,&s[i].r),s[i].id=i;
    sort(s+1,s+Q+1); int L=1;
    rep(i,1,Q){
          while(L<=s[i].r&&L<=N) add(a[L],L),++L;
          ans[s[i].id]=query(s[i].l);
    }
    rep(i,1,Q) printf("%d\n",ans[i]);
    return 0;
}

在线的做法,我们纪录一个前缀和 线性基,任然保留最大的位置。

#include
#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=500010;
int p[maxn][21],pos[maxn][21];
int main()
{
    int N,Q,L,R,x;
    scanf("%d",&N);
    rep(i,1,N) {
        rep(j,0,20) p[i][j]=p[i-1][j],pos[i][j]=pos[i-1][j];
        scanf("%d",&x); int ti=i;
        rep2(j,20,0){
            if(x&(1<=L&&(res^p[R][j])>res) res^=p[R][j];
        printf("%d\n",res);
    }
    return 0;
}

整场比赛更新完成

你可能感兴趣的:(codeforce)