Codeforces Round 271(Div. 2)

传送门

C.Captain Marmot (几何,点旋转)

思路

其中顺时针旋转为负,逆时针旋转为正,角度angle是弧度值,如旋转30度转换为弧度为: \(angle = pi/180 * 30\)

4、度与角度的转换
根据圆为\(360 º\),弧度为\(2π\),即 \(360º = 2π\)

4.1 角度转弧度:\(2π / 360 = π / 180 ≈ 0.0174rad\), 即: \(度数 * (π / 180) = 弧度\)
例如:将30º转为弧度rad
$ 30º * (π / 180)= 0.523320 rad $

4.2 弧度转角度: \(360 / 2π = 180 / π ≈ 57.3º\), 即: $ 弧度 * (180 / π) = 度数$
例如:将\(0.523320rad\)转为度º
$0.523320rad * (180 / π) = 29.9992352688º $

若o不是原点,则可先将a点坐标转换为相对坐标计算,计算结果再加上o点坐标。

参与计算的a点坐标实际应为 a - 0,最终计算公式如下:

\(b.x = ( a.x - o.x)*cos(angle) - (a.y - o.y)*sin(angle) + o.x\)

\(b.y = (a.x - o.x)*sin(angle) + (a.y - o.y)*cos(angle) + o.y\)

Flowers (DP)

思路

少于k的肯定全是1因为都只能放红色。

大于K的可以放红色\(dp[i-1]\) 或者连续的k个白色\(dp[i-k]\)

E - Pillars (DP+线段树+离散化)

思路

很明显的DP,但是数值太大,所以考虑离散化 然线段树取区间最大值

F - Ant colony (线段树区间gcd,线段树求最小值的个数)

思路

题意就是查询区间GCD 然后求出区间gcd的个数,后面的操作也可以主席树写

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+50;
int a[maxn];
#define bug cout<<"here"<<endl;
struct Tree{
    #define ls (o<<1)
    #define rs ((o<<1)|1)
    int gcd[maxn<<2],mi[maxn<<2],num[maxn<<2];
    void push_up(int o){
        gcd[o]=__gcd(gcd[ls],gcd[rs]);
    }
    void build(int o,int l,int r){
        if(l==r){
            mi[o]=gcd[o]=a[l];
            num[o]=1;
            return;
        }
        int mid=(l+r)/2;
        build(ls,l,mid);
        build(rs,mid+1,r);
        push_up(o);
    }
    int query(int o,int l,int r,int ql,int qr){
        if(ql<=l&&qr>=r){
            return gcd[o];
        }
        int mid=(l+r)/2;
        int gc=0;
        if(ql<=mid)gc=__gcd(gc,query(ls,l,mid,ql,qr));
        if(qr>mid)gc=__gcd(query(rs,mid+1,r,ql,qr),gc);
        return gc;
    }
}tree;

int sum[maxn*40],rt[maxn*40];
int lss[maxn*40],rss[maxn*40];
int cnt;
void update(int &o,int pre,int l,int r,int val){
    o=++cnt;
    lss[o]=lss[pre];rss[o]=rss[pre];
    sum[o]=sum[pre];
    if(l==r){sum[o]++;return;}
    int mid=(l+r)/2;
    if(val<=mid)update(lss[o],lss[pre],l,mid,val);
    else update(rss[o],rss[pre],mid+1,r,val);
}
int query(int o,int l,int r,int val){
    if(l==r){
        return sum[o];
    }
    int mid=(l+r)/2;
    if(val<=mid)return query(lss[o],l,mid,val);
    else return query(rss[o],mid+1,r,val);
}

int n;

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        update(rt[i],rt[i-1],1,1e9,a[i]);
    }
    tree.build(1,1,n);
    int m;
    cin>>m;
    while(m--){
        int l,r;
        cin>>l>>r;
        int gc=tree.query(1,1,n,l,r);
        int num=query(rt[r],1,1e9,gc);
        int num1=query(rt[l-1],1,1e9,gc);
        cout<<r-l+1-num+num1<<endl;

    }
    return 0;
}

posted @ 2019-03-28 19:59  luowentao  阅读(256)  评论(0编辑  收藏  举报