HLSC D15

配列

タイトル

説明

長有する\(N- \)配列\(B \) および長さ\(N- \)とゼロ配列の初期値(\ \)を、それぞれができる(\)を\アレイ間隔\([L、R]( 1≤リットル≤のR≤n)が\) 操作され、そのような区間内のその\(a_iを\)を加え、すべて1。任意のOperationsのQ.最小数よう\(私は\ N-leqslant \ 1 \ leqslant)がある\(= a_iをB_i \)

あなたは、これは、昨年の実際であることがわかります\(NOIP \)グループ向上させるために\(Day1T1 \)あなたのため単純すぎるが、ので、私たちは少し難易度のポイントを増加させました。

この問題では、長さを説明する\(\ N-)配列\(Bの\)を、そして合計であろう\(m個\)操作、または問い合わせ、それが二つのタイプに分けられます。

  • 1つのLRK:間隔\([L、R] \ ) の\(B_i \)プラス\(K \)
  • 2 LR:\(B_1、B_2、...、 B_、B_ {R + 1}、B_ {R + 2}、...、B_N \ {L-1}) の値は0、問い合わせアレイ\(Bの\)回答し、出力を対応します。

入力

最初の2つの行番号\(N、Mの\)配列と操作の数の長さを表します。

第二列\(N- \)の数は、アレイの初期状態を表す\(B \)

\(Mの\)正の整数与えるライン、\(OP \)の場合、操作の種類を表す\(OP = 1 \)は、次に3つの正の整数説明する\(L、R、kは、 OP = 2 \)は、2つの正の整数与える\(L、R&LTを\) ここで\(L、R、k個の\は ) 説明の意味は、タイトルに与えられています。

出力

すべてのために\(OP = 2 \)の動作、問い合わせの出力線は、回答と改行を対応する正の整数を表します。

サンプル入力

5 4
1 3 1 4 5
2 1 5
1 2 3 4
2 2 4
2 1 5

サンプル出力

7
6
6

ヒント

\(1 leqslant N-、M \ \ 100000 \ leqslant)
\(1 \ leqslantのL \ leqslant R&LT \ leqslant N- \)
\(1 \ B_iは、K \ 100000 \をleqslant leqslant)
いる(\ 30 \%の\)のデータ保証\(1 \ leqslant nは、m個
の\ leqslant 3000 \) のための\(70 \%の\)保証されたデータの\(1 \ leqslant N \ AST M \ leqslant25億\)

分析

私は、私が最後にゲームをシミュレートどのように多くのポイントがわからないので、私はそれを制御していない(30pts \)\を主要な暴力。

直接の正の解、レンジ動作、照会、ツリーラインまたは参照\を(BITは\) 2つだけ構築するために、あることを確かにある\(BIT \)元の配列:(よく書かれて)\(BIT \) 元の配列の差動アレイの片\(BIT \)

  1. 変更操作が元の配列を置く\(BIT \)差動アレイのビットは、シンクの元の配列内蔵ツリー差\を(BIT \)もツリー差を見て、
  2. クエリ動作は、直接第二歯に\(BIT \)プレフィックスと見えるし、元のアレイ追加する\(BIT \)\(1 \ SIMリットル\)回答。

コード

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

int n,m;
ll a[maxn],b[maxn],f[maxn],g[maxn];
inline int lowbit(int x) { return x & -x; }
inline void add(ll *t,int x,ll k) { while (x<=n) t[x]+=k, x+=lowbit(x); }
inline ll sum(ll *t,int x) { ll ans=0; while (x) ans+=t[x], x-=lowbit(x); return ans; }

int main()
{
    read(n);read(m);
    for (int i=1; i<=n; ++i) read(a[i]);
    for (int i=1; i<=n; ++i) b[i]=a[i]-a[i-1];//处理出差分数组
    for (int i=1; i<=n; ++i)
    {
        add(f,i,b[i]);
        if (b[i]>0) add(g,i,b[i]);//用于查询答案
    }
    while (m--)
    {
        int opt,l,r;
        read(opt);read(l);read(r);
        if (opt==1)
        {
            ll k;read(k);++r;//正好修改区间[l,r]
            add(f,l,k),add(f,r,-k);//BIT差分
            if (b[l]>0) add(g,l,-b[l]);
            if (b[r]>0) add(g,r,-b[r]);
            b[l]+=k,b[r]-=k;//在端点处打上标记
            if (b[l]>0) add(g,l,b[l]);
            if (b[r]>0) add(g,r,b[r]);
        }
        else write(sum(f,l)+sum(g,r)-sum(g,l)),puts("");
    }
    return 0;
}

タイトル

説明

デカルトシステムの視点座標、ある(N \)\長い\(D_X \) \(D_y、\) 高さ\(d_z \)ボックスは、ボックス側は座標軸に平行です。最初のために\(私は\)箱、その頂点の1つ\((X_I、Y_I、z_i)\) その後、彼の対角頂点\((X_I + D_X、Y_I + d_y、z_i + d_z) \) 。

二つの異なるボックスの\(I、J \)

彼らは共通点のIFFを持っている(| X_I-X - jが|≤d_x\ \≤d_z、| Y_I-y_j |≤d_y、| | z_i-z_j)を設定し、同時に。

このQ \(N- \)二つの異なるボックスにボックスがあるかどうか\(I、J(私は\ = jのない)\) 彼らは共通点を持っているよう。

入力

この質問複数のデータセット。

最初の行は、正の整数与える\(T \)を、データセットの数を表します。

各試験のために、最初の行は、4つの正の整数与える\(N、D_X、D_y ,, d_z \) およびボックスの数を各ボックスの長さと幅を、次\(N- \)ラインは、三を与えます正の整数\(X_I、Y_I、z_i \ ) ボックスのi番目の頂点を表します。

大量のデータのために、この問題は、最適化を読み込むことをお勧めします。

出力

CO \(T \)行は、各列は、各データ回答に対応します。

2つのボックスがある場合は共通点があり、出力が「\(\はい)」(引用符なし)、そうでない場合は出力「\(ノー\)。」

サンプル入力

2
2 2 3 4
1 1 1
3 4 5
2 2 3 4
1 1 1
3 4 6

サンプル出力

はい
ません

ヒント

\(1≤T≤千\)

\(100000 \≤2≤N)

\(1≤D_X、d_y、d_z≤1E9 \)

\(1≤X_I、Y_I、z_i≤1E9 \)

\(\和n≤1e6\)

前記ため\(30 \%\)保証されたデータの\(2≤n500 \≤)

前記のための\(60 \%の\)保証されたデータの\(N> 10000 \)のデータに一度だけ

分析

ゲームはこの問題を知らされているように見える多くの人々が暴力ポイントがたくさんあった後、量はとにかく、私はいつも暴力が唯一のポイントにそのポイントを得ることができ、私には関係ありません、いなくても分、ハム〜

私のために、様々な操作のファンは、すべてでは、コードで何を見ていないので、正解は、文字列のハッシュです。

コード

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10,p=1e6+3;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

int Case;
struct Orz
{
    int x,y,z;
    Orz(int a=0,int b=0,int c=0) : x(a),y(b),z(c) {}
    inline bool operator == (const Orz &a) const { return x==a.x && y==a.y && z==a.z; }
    inline int hash() { return abs(((((ll)x)<<20)+(((ll)y)<<10)+z))%p; }
};

struct Hash_table
{
    vector<Orz>V[p];
    vector<int>D[p];
    int t[p];

    inline void add(Orz x,int f)
    {
        int h=x.hash();
        if (t[h]!=Case)
        {
            V[h].clear();D[h].clear();
            t[h]=Case;
            V[h].push_back(x);
            D[h].push_back(f);
        }
        else
        {
            vector<Orz>::iterator itx=V[h].begin();
            vector<int>::iterator itd=D[h].begin();
            for ( ; itx!=V[h].end(); ++itx,++itd)
                if (*itx==x) { (*itd)+=f; return ; }
            V[h].push_back(x);
            D[h].push_back(f);
        }
    }

    inline int get(Orz x)
    {
        int h=x.hash();
        if (t[h]!=Case)
        {
            V[h].clear();D[h].clear();
            t[h]=Case;
            return 0;
        }
        else
        {
            vector<Orz>::iterator itx=V[h].begin();
            vector<int>::iterator itd=D[h].begin();
            for ( ; itx!=V[h].end(); ++itx,++itd)
                if (*itx==x) return *itd;
            return 0;
        }
    }
}M;

int n,dx,dy,dz;
int x[maxn],y[maxn],z[maxn];
inline bool check(int a,int b)
{
    if (!a) return 0;
    return abs(x[a]-x[b])<=dx && abs(y[a]-y[b])<=dy && abs(z[a]-z[b])<=dz;
}

int main()
{
    int T;read(T);
    for (Case=1; Case<=T; ++Case)
    {
        read(n);read(dx);read(dy);read(dz);
        for (int i=1; i<=n; ++i) read(x[i]),read(y[i]),read(z[i]);
        bool flag=0;
        for (int i=1; i<=n; ++i)
        {
            Orz now(x[i]/dx,y[i]/dy,z[i]/dz);
            int v=M.get(now);
            if (!v) M.add(now,i);
            else { flag=1; break; }
        }
        if (flag) { puts("Yes"); continue; }
        for (int i=1; i<=n && !flag; ++i)
        {
            int nx=x[i]/dx,ny=y[i]/dy,nz=z[i]/dz;
            for (int ox=-1; ox<=1; ++ox)
                for (int oy=-1; oy<=1; ++oy)
                    for (int oz=-1; oz<=1; ++oz) if (ox|oy|oz)
                        if (check(M.get(Orz(nx+ox,ny+oy,nz+oz)),i)) { flag=1; break; }
        }
        puts(flag?"Yes":"No");
    }
    return 0;
}

XORまたは剰余

タイトル

HDU 6275

説明

数を考えると、\(\ N-) 見つける
\ [(N〜MOD〜1 )〜XOR〜(N〜MODを〜2)〜XOR〜(N〜MOD〜3)〜XOR〜...〜XOR〜( N〜MOD〜(N-1 ))〜XOR〜(N〜MOD〜N)\]
ここで、modモジュロ演算であるxorC ++で(排他的論理和演算で使用して^示されています)

入力

ライン、正の整数\(N- \)

出力

ライン、正の整数の回答

サンプル入力

1 2 3 4 5

サンプル出力

0 0 1 1 2

ヒント

\(1 \ leqslant n個の\ leqslant 1,000,000,000,000 \)

前記ため\(20 \%\)保証されたデータの\(1 \ leqslant n個の\ leqslant 1,000,000 \)

前記ため\(50 \%\)保証されたデータの\(1 \ leqslant n個の\ leqslant 10億\)

前記ため\(80 \%の\)保証されたデータの\(1 \ leqslant N \ leqslant千億\)

分析

別に数および2.0から..

したがって、ブロック数論でなく、ヨーロッパ型の式に加えてインチ

なぜクラスのヨーロッパ式にそれを伴うだろうか?

発散やアイデアであるが存在するためと:見つけるそれぞれ個別にはい。

その後のローからハイに\(K \)応答ビット(0から始まる)実際に
\ [\ sum_ {i = 1 } ^ N \ lfloor \ FRAC {N〜MOD〜I} {2 ^ K} \ rfloor \ PMOD {2} = \ sum_ {i = 1} ^ N \ lfloor \ FRAC {N- \ lfloor FRAC \ {n}は{I} \ rfloor I} {2 ^ K} \ rfloor \ PMOD {2} \]

多くのユークリッドクラスのように\(のF \) 特定の派生もこのビットギャングスターに招待WorldWide_D\(ブログ\)観光に行くために、私は、下のコードを置きます。

コード

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

inline bool f(ll a,ll b,ll c,ll n)//类欧几里得
{
    if (!a) return (( (n+1)&(b/c) )&1ll)>0;
    if (a>=c || b>=c)
    {
        ll tmp=(n&1ll) ? (n+1)/2*n : n/2*(n+1);
        return (( (a/c)*tmp+(b/c)*(n+1)+f(a%c,b%c,c,n) )&1ll)>0;
    }
    else
    {
        ll m=(a*n+b)/c;
        return (( (n*m)^f(c,c-b-1,a,m-1) )&1ll)>0;
    }
}

int main()
{
    // int T;read(T);
    // while (T--)
    // {
        ll n;read(n);
        ll ans=0,t=min(30000000ll,n);
        for (ll i=1; i<=t; ++i) ans^=(n%i);//前lim直接暴力扫
        for (ll l=t+1,r; l<=n; l=r+1)
        {
            r=n/(n/l); ll lim=n/l*(r-l)+n%r,lans=0;
            for(ll k=1; k<=lim; k<<=1) lans+=f(n/l,n%r,k,r-l)*k;//后面用类欧公式搞过去
            ans^=lans;
        }
        write(ans),puts("");
    // }
    return 0;
}

おすすめ

転載: www.cnblogs.com/G-hsm/p/11355427.html
D15
D15
D15
D15
おすすめ