训练11

4012: What is the Rank?

题意:给定n个数,按顺序将数添加进集合中,并输出该数在当前集合中是第几大

#include<bits/stdc++.h>
using namespace std;
const int Max=45005;
struct node
{
     int x,y;
}e[Max];
int cmp(node a,node b)
{
    return a.y>b.y;
}
int cmp1(node a,node b)
{
    return a.x<b.x;
}
int f[Max];
void update(int x)
{
    for(int i=x;i<Max;i+=i&-i)
    {
        f[i]+=1;
    }
}
int query(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=i&-i)
    {
        sum+=f[i];
    }
    return sum;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&e[i].y);
        e[i].x=i;
    }
    sort(e+1,e+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        e[i].y=i;
    }
    sort(e+1,e+n+1,cmp1);
    for(int i=1;i<=n;i++)
    {
        update(e[i].y);
        printf("%d\n",query(e[i].y));
    }
}

//hash+树状数组

3656: Intersections

题意:给定一个圆和一条线段,求圆与线段是否相交

思路:1.线段两点均在圆内则不相交;

2.线段两点有一点在圆内,另一点在圆外则相交(有点在圆上为相交);

3.当两点均在圆外时,先求圆心在直线上的垂足,垂足在圆外则不相交,若垂足在圆内(包括圆上),继续判断线段两点是否相对垂足在同方向,同向为不相交,反向相交;

对点(x1,y1),(x2,y2)求出一般式:AX+BY+C=0

A=y2-y1    B=x1-x2     C=x2*y1-x1*y2

根据 A B C以及圆心(x,y)求出垂足(x3,y3)

x3=(b*b*x-a*b*y-a*c)/(a*a+b*b);y3=(a*a*y-a*b*x-b*c)/(a*a+b*b);

#include<bits/stdc++.h>
using namespace std;
void printY()
{
   printf("The line segment intersects the circle.\n");
}
void printN()
{
    printf("The line segment does not intersect the circle.\n");
}
int main()
{
    double x,y,r,x1,y1,x2,y2;
    while(~scanf("%lf%lf%lf",&x,&y,&r))
     {
         scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
         double a=y2-y1;
         double b=x1-x2;
         double c=x2*y1-x1*y2;
         double x3=(b*b*x-a*b*y-a*c)/(a*a+b*b);
         double y3=(a*a*y-a*b*x-b*c)/(a*a+b*b);
         if((x-x1)*(x-x1)+(y-y1)*(y-y1)<r*r)
         {
             if((x-x2)*(x-x2)+(y-y2)*(y-y2)<r*r)
             printN();
             else
             printY();
         }
         else
         {
             if((x-x2)*(x-x2)+(y-y2)*(y-y2)<r*r)
               printY();
             else
             {
                 if((x-x3)*(x-x3)+(y-y3)*(y-y3)<=r*r)
                 {
                     if(x3==x2)
                     {
                         if((y3-y2)/abs(y3-y2)==(y3-y1)/abs(y3-y1))
                          printN();
                         else
                          printY();
                     }
                     else
                     {
                         if((x3-x2)/abs(x3-x2)==(x3-x1)/abs(x3-x1))
                          printN();
                         else
                          printY();
                     }
                 }
                 else
                 {
                     printN();
                 }
             }
         }
     }
}

//数学 

4613: Number of Battlefields

题意:给定一个周长p,问有多少形状的周长为p(不能为矩形)

矩阵快速幂求斐波那契数列

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=987654321;
void mul(ll b[2][2],ll a[2][2])
{
    ll c[2][2]={0};
    for(int i=0;i<=1;i++)
    {
        for(int j=0;j<=1;j++)
        {
            c[i][j]=b[i][0]*a[0][j]%MOD+b[i][1]*a[1][j]%MOD;
        }
    }
    memcpy(b,c,sizeof(c));
}
void power(ll a[2][2],int p)
{
    ll b[2][2]={1,0,1,0};
    while(p)
    {
        if(p&1)
        {
            mul(b,a);
        }
        mul(a,a);
        p/=2;
    }
    memcpy(a,b,sizeof(b));
}
int main()
{
    int p;
    while(scanf("%d",&p),p)
    {
        if (p&1||p<8)
        {
            printf("0\n");
            continue;
        }
        p=(p-4)/2;
        ll a[2][2]={1,1,1,0};
        power(a,2*p);
        printf("%lld\n",(a[1][0]-p-1+MOD)%MOD);
    }
}

4505: KOSARE

题意:有n个盒子,m种类的玩具。n个盒子各自装有一定不同种类的玩具,现在请你选择一些盒子,使得这些盒子的玩具包含全部种类;问有多少种选择能够满足条件

#include<bits/stdc++.h>
using namespace std;
const int Max=(1<<20)+5;
const int Mod=1000000007;
int cnt[Max],num[Max],ans[Max];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    cnt[0]=1;
    int f=1<<m;
    for(int i=1;i<=n;i++)
    {
        cnt[i]=(cnt[i-1]*2)%Mod;
        int k,s=0;
        scanf("%d",&k);
        for(int j=1;j<=k;j++)
        {
            int x;
            scanf("%d",&x);
            s+=1<<x-1;
        }
        num[s]++;
    }
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<f;j++)
        {
            if(j&(1<<i))num[j]+=num[j-(1<<i)];
        }
    }
    for(int i=0;i<f;i++)
    {
        ans[i]=cnt[num[i]];
    }
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<f;j++)
        {
            if(j&(1<<i))ans[j]=(ans[j]-ans[j-(1<<i)]+Mod)%Mod;
        }
    }
    printf("%d\n",ans[f-1]%Mod);
}

//容斥原理+状压DP

6043: Tunnel Warfare

题意:一条直线上有n个村庄,目前有三种操作,D操作,将该村庄破坏,Q操作,查询有该村庄直接连接或间接连接的村庄数(包括自身),R操作将最近被破坏的村庄重建;

#include<bits/stdc++.h>
using namespace std;
const int Max=50005;
struct node{
   int llen,rlen,mlen;
}e[Max*4];
void Build(int l,int r,int i)
{
    e[i].llen=e[i].rlen=e[i].mlen=r-l+1;
    int mid=(l+r)/2;
    if(l==r)return ;
    Build(l,mid,i*2);
    Build(mid+1,r,i*2+1);
}
void Update(int l,int r,int i,int nod,int flag)
{
    if(l==r)
    {
        e[i].llen=e[i].rlen=e[i].mlen=flag;
        return ;
    }
    int mid=(l+r)/2;
    if(nod<=mid)Update(l,mid,i*2,nod,flag);
    else Update(mid+1,r,i*2+1,nod,flag);
    e[i].llen=e[2*i].llen;
    e[i].rlen=e[2*i+1].rlen;
    e[i].mlen=max(max(e[i*2].mlen,e[i*2+1].mlen),e[i*2].rlen+e[i*2+1].llen);
    if(e[2*i].llen==mid-l+1)
        e[i].llen+=e[2*i+1].llen;
    if(e[i*2+1].rlen==r-mid)
        e[i].rlen+=e[2*i].rlen;
}
int Query(int l,int r,int i,int x)
{
    if(l==r||e[i].mlen==0||e[i].mlen==r-l+1)
    {
        return e[i].mlen;
    }
    int mid=(l+r)/2;
    if(x<=mid)
    {
        if(x>=mid-e[i*2].rlen+1)
            return Query(l,mid,i*2,x)+Query(mid+1,r,i*2+1,mid+1);
         else
            return Query(l,mid,i*2,x);
    }
    else
    {
        if(x<=mid+1+e[i*2+1].llen-1)
            return Query(mid+1,r,i*2+1,x)+Query(l,mid,i*2,mid);
        else
            return Query(mid+1,r,i*2+1,x);
    }
}
stack<int> st;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    Build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        getchar();
        char ch;
        scanf("%c",&ch);
        if(ch=='D')
        {
            int x;
            scanf("%d",&x);
            Update(1,n,1,x,0);
            st.push(x);
        }
        else if(ch=='Q')
        {   int x;
            scanf("%d",&x);
            printf("%d\n",Query(1,n,1,x));
        }
        else
        {
            if(!st.size())continue;
            int x=st.top();
            st.pop();
            Update(1,n,1,x,1);
        }
    }
}

 

猜你喜欢

转载自www.cnblogs.com/llhsbg/p/11864541.html
今日推荐