您的位置:首页 > 其它

ROUND 2の Asia - Phuket2013

2015-08-03 10:45 267 查看
签到啥的就不说了。

C:Counting Lattice Squares

分析:让你数奇数的面积的三角形,我们从奇数长度出发,每次奇数长度的小的正方形有(n-i+1)(m-i+1),

这些奇数长度的小正方形中存在的斜正方形数目(i/2*2),加起来就是(n-i+1)(m-i+1)(i/2*2+1)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int INF=0x3f3f3f3f;
typedef long long LL;
int n,m;

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(n+m==0)
            continue;
        LL ans=0;
        int mi=min(n,m);
        for(int i=1;i<=mi;i+=2)
            ans+=(LL)(n-i+1)*(m-i+1)*(i/2*2+1);
        printf("%lld\n",ans);
    }
    return 0;
}


E:Airport Sort

分析:对于第一种交换来说,就是给他们分块求逆序数,对于第二种交换,我们采用贪心思想

前面的肯定要填每个块中前面的空,所以就直接贪心。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int maxn=(1e5+100);
int a[maxn],pos[maxn];
int c[maxn+100],vis[maxn];
int t,n,k;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x)
{
    while(x<maxn)
    {
        c[x]++;
        x+=lowbit(x);
    }
}
int query(int x)
{
    int sum=0;
    while(x>0)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
int main()
{
    int cas=1;
    scanf("%d",&t);
    while(t--)
    {
        int t1=0,t2=0;
        CLEAR(c,0);
        CLEAR(vis,0);
        scanf("%d%d",&n,&k);
        REPF(i,1,n)
        {
           scanf("%d",&a[i]);
           pos[i]=(a[i]-1)/k+1;
        }
        for(int i=1;i<=n;i++)
        {
            t1+=query(maxn)-query(pos[i]);
            update(pos[i]);
        }
        for(int i=1;i<=n;i++)
        {
            t2=max(t2,abs(1+(pos[i]-1)*k+vis[pos[i]]-i));
            vis[pos[i]]++;
        }
        printf("Case %d: %d\n",cas++,t1-t2);
    }
    return 0;
}


J:Minimal Subarray Length

分析:对于正数来说,我们直接尺取就完了,所以最开始我写了个改良的尺取,然后就挂了,

这道题显然行,我们考虑区间最大值,最小值可以二分的性质打个ST表,直接二分搞就行了复杂度nlog(n)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int maxn=(1e5+100)*5;
LL a[maxn],sum[maxn];
LL dp_max[maxn][20];
int t,n,s;
void init()
{
    for(int i=1;i<=n;i++)
       dp_max[i][0]=sum[i];
    for(int j=1;j<18;j++)
       for(int i=1;i+(1<<j)-1<=n;i++)
           dp_max[i][j]=max(dp_max[i][j-1],dp_max[i+(1<<(j-1))][j-1]);
}
int r_max(int l,int r)
{
    int k=(int)(log(r-l+1)/log(2.0));
    return max(dp_max[l][k],dp_max[r-(1<<k)+1][k]);
}
int solve()
{
    init();
    int ans=INF;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>=0)
        {
            int l=i,r=n;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                LL val=r_max(i,mid);
                if(val-sum[i-1]>=s)
                    r=mid-1;
                else
                    l=mid+1;
            }
            if(l<=n)
               ans=min(ans,l-i+1);
        }
    }
    return ans==INF?-1:ans;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&s);
        int flag=0;
        REPF(i,1,n)
        {
            scanf("%lld",&a[i]);
            if(a[i]>=s) flag=1;
            sum[i]=sum[i-1]+a[i];

        }
        if(flag)
            puts("1");
        else if(s<0&&!flag)
            puts("-1");
        else
            printf("%d\n",solve());
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: