codefroces round #254 div1

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves Physics, and he enjoys calculating density.

Almost everything has density, even a graph. We define the density of a non-directed graph (nodes and edges of the graph have some values) as follows:

where  v is the sum of the values of the nodes,  e is the sum of the values of the edges.

Once DZY got a graph G, now he wants to find a connected induced subgraph G' of the graph, such that the density of G' is as large as possible.

An induced subgraph G'(V', E') of a graph G(V, E) is a graph that satisfies:

  • ;
  • edge  if and only if , and edge ;
  • the value of an edge in G' is the same as the value of the corresponding edge in G, so as the value of a node.

Help DZY to find the induced subgraph with maximum density. Note that the induced subgraph you choose must be connected.

Input

The first line contains two space-separated integers n (1 ≤ n ≤ 500). Integer n represents the number of nodes of the graph Gm represents the number of edges.

The second line contains n space-separated integers xi (1 ≤ xi ≤ 106), where xi represents the value of the i-th node. Consider the graph nodes are numbered from 1 to n.

Each of the next m lines contains three space-separated integers ai, bi, ci (1 ≤ ai < bi ≤ n; 1 ≤ ci ≤ 103), denoting an edge between node ai and bi with value ci. The graph won't contain multiple edges.

Output

Output a real number denoting the answer, with an absolute or relative error of at most 10 - 9.

Sample test(s)
input
1 0
1
output
0.000000000000000
input
2 1
1 2
1 2 1
output
3.000000000000000
input
5 6
13 56 73 98 17
1 2 56
1 3 29
1 4 42
2 3 95
2 4 88
3 4 63
output
2.965517241379311
Note

In the first sample, you can only choose an empty subgraph, or the subgraph containing only node 1.

In the second sample, choosing the whole graph is optimal.

题意:给定一个n个点m条边的无向图,每个点、每条边都有权值,找一个诱导子图是其点权和除以边权和值最大,输出最大值。

思路:只选一条边,对应的点权和除以边权中选最大值。下面给出大致的证明:

设最大值对应的点是u 、v, 即( w[ u ] +w[ v ] ) / w[ u , v ]最大,我们考虑在其两点基础上填边,不妨设v ' 与v相连,那么( w[ v ] + w[ v ' ] ) / w[ v, v ' ]<= ( w[ u ] +w[ v ] ) / w[ u , v ],

而v的点权只能用一次,那么必然 ( w[ u ] + w[ v ] + w[ v ' ] ) / ( w[ u,v ] + w[ v,v ' ] ) <=( w[ u ] +w[ v ] ) / w[ u , v ] ,成环的比例会更小,所以应只取一条比例最大的边,详见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=500+100;
int n,m;
int x[MAXN];
int main()
{
    //freopen("text.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&x[i]);
        double ans=0.0;
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            ans=max(ans,1.0*(x[u]+x[v])/w);
        }
         printf("%.15f\n",ans);
    }
    return 0;
}


time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves Fast Fourier Transformation, and he enjoys using it.

Fast Fourier Transformation is an algorithm used to calculate convolution. Specifically, if ab and c are sequences with length n, which are indexed from 0 to n - 1, and

We can calculate c fast using Fast Fourier Transformation.

DZY made a little change on this formula. Now

To make things easier, a is a permutation of integers from 1 to n, and b is a sequence only containing 0 and 1. Given a and b, DZY needs your help to calculate c.

Because he is naughty, DZY provides a special way to get a and b. What you need is only three integers ndx. After getting them, use the code below to generate a and b.

//x is 64-bit variable;
function getNextX() {
    x = (x * 37 + 10007) % 1000000007;
    return x;
}
function initAB() {
    for(i = 0; i < n; i = i + 1){
        a[i] = i + 1;
    }
    for(i = 0; i < n; i = i + 1){
        swap(a[i], a[getNextX() % (i + 1)]);
    }
    for(i = 0; i < n; i = i + 1){
        if (i < d)
            b[i] = 1;
        else
            b[i] = 0;
    }
    for(i = 0; i < n; i = i + 1){
        swap(b[i], b[getNextX() % (i + 1)]);
    }
}

Operation x % y denotes remainder after division x by y. Function swap(x, y) swaps two values x and y.

Input

The only line of input contains three space-separated integers n, d, x (1 ≤ d ≤ n ≤ 100000; 0 ≤ x ≤ 1000000006). Because DZY is naughty, x can't be equal to 27777500.

Output

Output n lines, the i-th line should contain an integer ci - 1.

Sample test(s)
input
3 1 1
output
1
3
2
input
5 4 2
output
2
2
4
5
5
input
5 4 3
output
5
5
5
5
4
Note

In the first sample, a is [1 3 2]b is [1 0 0], so c0 = max(1·1) = 1c1 = max(1·0, 3·1) = 3c2 = max(1·0, 3·0, 2·1) = 2.

In the second sample, a is [2 1 4 5 3]b is [1 1 1 0 1].

In the third sample, a is [5 2 1 4 3]b is [1 1 1 1 0].


题意:求 

思路:用pos数组记录每个a[ i ]值的下标,同时用map记录第几个1在b数组的位置,其中map[ 0 ]是b数组中1的个数。那么用cnt控制循环次数,a[ i ]值从大到小更新c数组,对于

没有更新的c[ i ]值, 最后更新一下,详见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=100000+100;
int n,d;
ll x;
int a[MAXN],b[MAXN],c[MAXN],pos[MAXN],map[MAXN];
int getNextX()
{
    x=(x*37+10007)%1000000007;
    return x;
}
void initAB()
{
    for(int i=0;i<n;i++)
        a[i]=i+1;
    for(int i=0;i<n;i++)
        swap(a[i],a[getNextX()%(i+1)]);
    for(int i=0;i<n;i++)
        if(i<d)
            b[i]=1;
        else
            b[i]=0;
    for(int i=0;i<n;i++)
        swap(b[i],b[getNextX()%(i+1)]);
    for(int i=0;i<n;i++)
        pos[a[i]]=i;
    for(int i=0;i<n;i++)
        if(b[i])
            map[++map[0]]=i;
}
int main()
{
    //freopen("text1.txt","w",stdout);
    scanf("%d%d%I64d",&n,&d,&x);
    initAB();
    int cnt=0;
    for(int i=n;i>=1 && cnt<=10000000;i--)
        for(int j=1;j<=map[0];j++,cnt++)
            if(pos[i]+map[j]<n)
                c[pos[i]+map[j]]=max(c[pos[i]+map[j]],i);
    for(int i=0;i<n;i++)
        if(!c[i])
            for(int j=1;j<=map[0];j++)
            {
                if(i<map[j])
                    break;
                else
                    c[i]=max(c[i],a[i-map[j]]);
            }
    for(int i=0;i<n;i++)
        printf("%d\n",c[i]);
    return 0;
}



time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves colors, and he enjoys painting.

On a colorful day, DZY gets a colorful ribbon, which consists of n units (they are numbered from 1 to n from left to right). The color of thei-th unit of the ribbon is i at first. It is colorful enough, but we still consider that the colorfulness of each unit is 0 at first.

DZY loves painting, we know. He takes up a paintbrush with color x and uses it to draw a line on the ribbon. In such a case some contiguous units are painted. Imagine that the color of unit i currently is y. When it is painted by this paintbrush, the color of the unit becomes x, and the colorfulness of the unit increases by |x - y|.

DZY wants to perform m operations, each operation can be one of the following:

  1. Paint all the units with numbers between l and r (both inclusive) with color x.
  2. Ask the sum of colorfulness of the units between l and r (both inclusive).

Can you help DZY?

Input

The first line contains two space-separated integers n, m (1 ≤ n, m ≤ 105).

Each of the next m lines begins with a integer type (1 ≤ type ≤ 2), which represents the type of this operation.

If type = 1, there will be 3 more integers l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 108) in this line, describing an operation 1.

If type = 2, there will be 2 more integers l, r (1 ≤ l ≤ r ≤ n) in this line, describing an operation 2.

Output

For each operation 2, print a line containing the answer — sum of colorfulness.

Sample test(s)
input
3 3
1 1 2 4
1 2 3 5
2 1 3
output
8
input
3 4
1 1 3 4
2 1 1
2 2 2
2 3 3
output
3
2
1
input
10 6
1 1 5 3
1 2 7 9
1 10 10 11
1 3 8 12
1 1 10 3
2 1 10
output
129
Note

In the first sample, the color of each unit is initially [1, 2, 3], and the colorfulness is [0, 0, 0].

After the first operation, colors become [4, 4, 3], colorfulness become [3, 2, 0].

After the second operation, colors become [4, 5, 5], colorfulness become [3, 3, 2].

So the answer to the only operation of type 2 is 8.


题意:有n件制服,第i件衣服初始颜色为i。假设第i件衣服颜色当前为y,染色后为x,那么颜色的colorfulness就会增加 | x - y |

有两种操作: (1) 将 [ l , r ]之间的衣服染成x  (2) 询问[ l , r ]之间的colorfulness和。

思路: 线段树成段更新,lazy标记。 只不过此题还需要一个lazy(程序中即col,记录该段衣服的颜色),之后就是基本的线段树了。但是需要注意的是update的时候,

即使segtree[ rt ].l == l && r == segtree[ rt ].r 也不能直接更新,因为必须要segtree[ rt ].col >0( 即该段衣服颜色均统一的时候)才能更新。详见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
const int MAXN=100000+100;
int n,m;
struct node
{
    int l,r;
    ll sum,col,lazy;
    ll size(){ return r-l+1; }
}segtree[MAXN<<2];
void build(int rt,int l,int r)
{
    segtree[rt].l=l,segtree[rt].r=r;
    segtree[rt].col=segtree[rt].sum=segtree[rt].lazy=0;
    if(segtree[rt].l==segtree[rt].r)
    {
        segtree[rt].col=l;
        return ;
    }
    int mid=(l+r)>>1;
    build(L(rt),l,mid); build(R(rt),mid+1,r);
}
void push_down(int rt)
{
    if(segtree[rt].l==segtree[rt].r)
        return ;
    if(segtree[rt].lazy)
    {
        segtree[L(rt)].lazy+=segtree[rt].lazy;
        segtree[R(rt)].lazy+=segtree[rt].lazy;
        segtree[L(rt)].sum+=segtree[L(rt)].size()*segtree[rt].lazy;
        segtree[R(rt)].sum+=segtree[R(rt)].size()*segtree[rt].lazy;
        segtree[rt].lazy=0;
    }
    if(segtree[rt].col)
        segtree[L(rt)].col=segtree[R(rt)].col=segtree[rt].col;
}
void push_up(int rt)
{
    if(segtree[L(rt)].col == segtree[R(rt)].col && segtree[L(rt)].col)
        segtree[rt].col=segtree[L(rt)].col;
    else
        segtree[rt].col=0;
    segtree[rt].sum=segtree[L(rt)].sum+segtree[R(rt)].sum;
}
void update(int rt,int l,int r,ll col)
{
    push_down(rt);
    if(segtree[rt].l == l && r == segtree[rt].r &&segtree[rt].col )
    {
        segtree[rt].sum+=segtree[rt].size()*abs(segtree[rt].col-col);
        segtree[rt].lazy+=abs(segtree[rt].col-col);
        segtree[rt].col=col;
        return ;
    }
    int mid=(segtree[rt].l+segtree[rt].r)>>1;
    if(l>mid)
        update(R(rt),l,r,col);
    else if(r<=mid)
        update(L(rt),l,r,col);
    else
    {
        update(L(rt),l,mid,col);
        update(R(rt),mid+1,r,col);
    }
    push_up(rt);
}
ll query(int rt,int l,int r)
{
    push_down(rt);
    if( l == segtree[rt].l && r == segtree[rt].r)
        return segtree[rt].sum;
    int mid=(segtree[rt].l+segtree[rt].r)>>1;
    if(l>mid)
        return query(R(rt),l,r);
    else if(r<=mid)
        return query(L(rt),l,r);
    else
        return query(L(rt),l,mid)+query(R(rt),mid+1,r);
}
int main()
{
    //freopen("text.txt","r",stdin);
    int cmd,l,r;
    ll x;
    while(~scanf("%d%d",&n,&m))
    {
        build(1,1,n);
        while(m--)
        {
            scanf("%d%d%d",&cmd,&l,&r);
            if(cmd==1)
            {
                scanf("%I64d",&x);
                update(1,l,r,x);
            }
        else
            printf("%I64d\n",query(1,l,r));
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值