ゴシップ
この2日間の試験は、ああ、暴力をプレイすると、200ポイントのqwqを持って、本当に素晴らしいです。
フェイス質問
T1
溶液
それはキューブを差分しているため、キューブは貧しい式とみなすことができます。
\((AB)^ 3 =(A-B)×(^ 2 + \倍B + B ^ 2)\ \)
そしてので\(P \)素数なので、\((AB&)\)と\((^ 2 + \回B + B ^ 2)\) 1がなければなりません。明らかに、\は((2 + A ^ \タイムズB + B ^ 2)\) 1、このようにして得られたよりも大きくなければならない(\(AB&))\すなわち、1であり、\(P \)がなければなりません隣接する二つの数字の間キューブ差。
我々は、ときにいくつかのサイクルが、見つけることができる見つけることができる(K = 577351 \)を\場合、\(K ^ 3-(1-K)。3 ^ \)値が最初より大きい\(10 ^ {12} \) 。だから、直接、最初から、解答または列挙値がより大きい見つけてきました\(P \)最後にすることができます。
時間複雑\(O(N \回MAXK )\)
コード
#include<bits/stdc++.h>
#define del(a,i) memset(a,i,sizeof(a))
#define ll long long
#define inl inline
#define il inl void
#define it inl int
#define ill inl ll
#define re register
#define ri re int
#define rl re ll
#define mid ((l+r)>>1)
#define lowbit(x) (x&(-x))
#define INF 0x3f3f3f3f
using namespace std;
template<class T>il read(T &x){
int f=1;char k=getchar();x=0;
for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
x*=f;
}
template<class T>il print(T x){
if(x/10) print(x/10);
putchar(x%10+'0');
}
ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
it qpow(int x,int m,int mod){
int res=1,bas=x%mod;
while(m){
if(m&1) res=(res*bas)%mod;
bas=(bas*bas)%mod,m>>=1;
}
return res%mod;
}
const int MAXN = 577351,maxn = 578;
ll T,p;
bool check(ll p){
for(ri i=1;i<=MAXN;++i){
rl mns=1ll*i*i*i-1ll*(i-1)*(i-1)*(i-1);
if(mns==p)
return true;
else if(mns>p) return false;
}
return false;
}
int main()
{
freopen("cubicp.in","r",stdin);
freopen("cubicp.out","w",stdout);
read(T);
while(T--){
read(p);
if(check(p)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
T2
溶液
\(70pts \)プラクティス:
以下のための\(60 \)データの%、\(N <= 1000、K <= 20である\) 。
明らかに\(O(N ^ 2 \回K)\) アルゴリズムをすることによって実行されています。
DPを考えてみましょうこれは、サブジェクト名ではありません
我々は定義\(DP_ {I、Jは} \) の到着を表し\(Iは\)に分割数、\(J \)得られた最小セグメント。
伝達方程式は簡単です。
\(DP_ {I、J} = MIN(DP_ {S、J-1} + val_ {S + 1、I})\)
我々の唯一の前処理\(val_ {I、Jは} \) を直接転送することができます。
私たちは、内部の各ファイルのすべてのポイントがあり、データの範囲を見て\(a_iを\)とまったく同じで。
私たちの簡単な分析、我々は見つけること、私たちはしているとき(k個\)\際に同じ値、\(k個\)も大きく貢献して\(K-1 \)差が大きくなるので、我々はそれをしたいです\(N \)のように分割数平均\(K \)部品。
場合\(Nは\)する(K \)\分割し、各セグメントのサイズは(N / K \)\ ;割り切れない、余分な場合\(REST \)数は、それらに等分します\(休憩\)間隔の。
回答の算出に各セグメント間の良好な寄与、\(ヴァル= \ {FRACサイズ\タイムズ(-size。1)} {2} \)
そして、直接の答えであるの数を乗じました。
コード
#include<bits/stdc++.h>
#define del(a,i) memset(a,i,sizeof(a))
#define ll long long
#define inl inline
#define il inl void
#define it inl int
#define ill inl ll
#define re register
#define ri re int
#define rl re ll
#define mid ((l+r)>>1)
#define lowbit(x) (x&(-x))
#define INF 0x3f3f3f3f
using namespace std;
template<class T>il read(T &x){
int f=1;char k=getchar();x=0;
for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
x*=f;
}
template<class T>il print(T x){
if(x/10) print(x/10);
putchar(x%10+'0');
}
ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
it qpow(int x,int m,int mod){
int res=1,bas=x%mod;
while(m){
if(m&1) res=(res*bas)%mod;
bas=(bas*bas)%mod,m>>=1;
}
return res%mod;
}
const int MAXN = 1e3+1;
int n,k,a[MAXN],val[MAXN][MAXN],w,dp[21][MAXN],cnt[MAXN][MAXN],last[MAXN];
int main()
{
freopen("dp.in","r",stdin);
freopen("dp.out","w",stdout);
read(n),read(k),del(dp,0x3f);
if(n<=1000){
for(ri i=1;i<=n;++i) read(a[i]);
for(ri i=1;i<=n;++i){
val[1][i]=val[1][i-1]+cnt[a[i]][last[a[i]]];
cnt[a[i]][i]=cnt[a[i]][last[a[i]]]+1,last[a[i]]=i;
}
for(ri i=2;i<=n;++i){
ri mns=0;
for(ri j=i;j<=n;++j){
if(a[j]==a[i-1]) mns++;
val[i][j]=val[i-1][j]-mns;
}
}
dp[0][0]=0;
for(ri s=1;s<=k;++s)
for(ri i=1;i<=n;++i)
for(ri j=0;j<i;++j)
dp[s][i]=min(dp[s][i],dp[s-1][j]+val[j+1][i]);
printf("%d",dp[k][n]);
}
else{
for(ri i=1;i<=n;++i) read(w);
ri add=n%k,len=n/k;
printf("%d",(k-add)*len*(len-1)/2+add*(len+1)*len/2);
}
return 0;
}
\(\ 100)は、プラクティスをPTS:
オーダー\(DP_ {I、J} \) 前進を表す\(Iは\)に数\(J \)最小値セグメント。列挙ブレークポイント\(K \)がある(DP_ {I、J} \)\ = \(MIN(DP_ {K、J-sum_ {+}。1. 1 + K、I})\) 。実際に、この\(k個の\)は、古典的な1D1D動的プログラミングを使用するように最適化単調です。どのようなああ(霧
コード
#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
typedef long long LL;
int c[N],a[N];
LL f[N],g[N];
int p,q,n,k;
LL tot;
void move(int l,int r)
{
while (l<p) p--,tot+=c[a[p]],c[a[p]]++;
while (r>q) q++,tot+=c[a[q]],c[a[q]]++;
while (p<l) c[a[p]]--,tot-=c[a[p]],p++;
while (r<q) c[a[q]]--,tot-=c[a[q]],q--;
}
void work(int l,int r,int fl,int fr)
{
if (fl>fr) return;
int mid=(fl+fr)>>1,mi;
LL mx=1LL<<60;
for (int i=l;i<=r;i++)
if (i<mid)
{
move(i+1,mid);
if (f[i]+tot<mx) mx=f[i]+tot,mi=i;
}
g[mid]=mx;
work(l,mi,fl,mid-1);
work(mi,r,mid+1,fr);
}
int main()
{
freopen("dp.in","r",stdin);
freopen("dp.out","w",stdout);
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
f[0]=0;
for (int i=1;i<=n;i++) f[i]=1LL<<60;
while (k--)
{
p=1,q=0,tot=0;
for (int i=1;i<=n;i++) c[i]=0;
work(0,n-1,1,n);
for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0;
}
cout<<f[n];
return 0;
}
T3
溶液
Xの動作のための間隔ペイは、一方のみが矛盾最小のすべてのセクションに起こる:xの範囲を超えて横断面を含む最小値について。
したがって、我々は半分の答えは、すべて最小降順た後、使用やメンテナンスチェックを設定することができます。私は理解できませんでした。。。
コード
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000011
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
using namespace std;
int n, q, ans;
int f[N];
struct node
{
int x, y, z;
}p[N], t[N];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
}
inline bool cmp(node x, node y)
{
return x.z > y.z;
}
inline int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
inline bool check(int k)
{
int i, j, x, y, lmin, lmax, rmin, rmax;
for(i = 1; i <= n + 1; i++) f[i] = i;
for(i = 1; i <= k; i++) t[i] = p[i];
std::sort(t + 1, t + k + 1, cmp);
lmin = lmax = t[1].x;
rmin = rmax = t[1].y;
for(i = 2; i <= k; i++)
{
if(t[i].z < t[i - 1].z)
{
if(find(lmax) > rmin) return 1;
for(j = find(lmin); j <= rmax; j++)
f[find(j)] = find(rmax + 1);
lmin = lmax = t[i].x;
rmin = rmax = t[i].y;
}
else
{
lmin = min(lmin, t[i].x);
lmax = max(lmax, t[i].x);
rmin = min(rmin, t[i].y);
rmax = max(rmax, t[i].y);
if(lmax > rmin) return 1;
}
}
// cout<<find(1)<<endl;
if(find(lmax) > rmin) return 1;
return 0;
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
int i, x, y, mid;
n = read();
q = read();
for(i = 1; i <= q; i++)
p[i].x = read(), p[i].y = read(), p[i].z = read();
x = 1, y = q;
//cout<<check(2)<<endl;
//return 0;
while(x <= y)
{
mid = (x + y) >> 1;
if(check(mid)) ans = mid, y = mid - 1;
else x = mid + 1;
}
printf("%d\n", ans);
return 0;
}
概要
交換が終了した後、ギャングトピック私は彼女がああも、それは理解していなかったものですまだ弱いがわかりました。。。
または良い燃料ああへ。