概要:データ構造fwが覆されました...
T1
トピックの主なアイデア:長さkの2つの文字列a、ba、bを与えるA 、b、長さnの2つの文字列c、dc、dc 、d (k <= n)(k <= n)(k<=n )、最小llを見つけるLその結果、C、DC、Dc 、dのlの先頭にある長さkの部分文字列は、a、ba、bとまったく同じです。A 、bが一致します。
n、k <= 1 e 6 n、k <= 1e6n 、k<=1 e 6
今行ってる!!また、筆記試験の必需品です!!!
(実際には、n個のゲームでもハッシュがあります。誰もがそれを理解しています。ハッシュをよく学んだら、書かれたテストに合格する必要があります。jpg)
C ++コード:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ull unsigned long long
#define maxn 10000005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline int read()
{
int x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {
x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
ull h1[maxn],h2[maxn],p1,p2,B[maxn];
int n,k,x;
inline ull gh(int l,int r,int opt)
{
if(opt==1) return h1[r]-h1[l-1]*B[r-l+1];
else return h2[r]-h2[l-1]*B[r-l+1];
}
int main()
{
freopen("t1.in","r",stdin);
k=read(); B[0]=1; rep(i,1,maxn-5) B[i]=B[i-1]*233;
rep(i,1,k) x=read(),p1=p1*233+x;
rep(i,1,k) x=read(),p2=p2*233+x;
n=read();
rep(i,1,n) x=read(),h1[i]=h1[i-1]*233+x;
rep(i,1,n) x=read(),h2[i]=h2[i-1]*233+x;
int F=0;
rep(l,1,n)
{
int r=l+k-1; if(r>n) break;
ull x1=gh(l,r,1),x2=gh(l,r,2);
if(x1==p1&&x2==p2) {
F=l; break;}
}
cout<<F<<endl;
return 0;
}
T2
トピックの主な考え方:n * mの行列が与えられた場合、一度に4方向で自分の体重より少ない場所に行くことができ、開始点を選択して最長の経路を見つける必要があります。
n、m <= 1000 n、m <= 1000n 、メートル<=1 0 0 0
元の質問へのリンクを置くだけです:SHOI 2002 SHOI2002S H O I 2 0 0 2スキー
メモリ検索、dp [i] [j] dp [i] [j]を検討d p [ i ] [ j ]は在(i、j)(i、j)(私、j )場所までの最長の道。
次に、各ポイントは一度だけdfsになるため、全体的な複雑度はO(n ∗ m)O(n * m)です。O (n∗m ) ...
理解しにくいかもしれませんが、詳細についてはコードを参照してください...コードは非常に理解しやすいです。
Javaコード:
import java.io.*;
import java.util.*;
public class zbr01
{
public static int [][]a=new int [1005][1005];
public static int [][]dp=new int [1005][1005];
public static int [][]k={
{
1,0},{
0,1},{
-1,0},{
0,-1}};
public static int n,m,ans;
public static int dfs(int x,int y)
{
if(dp[x][y]!=0) return dp[x][y];
for(int i=0;i<=3;i++)
{
int tx=x+k[i][0],ty=y+k[i][1];
if(tx<1||ty<1||tx>n||ty>m||a[tx][ty]>=a[x][y]) continue;
dp[x][y]=Math.max(dp[x][y],1+dfs(tx,ty));
}
return dp[x][y];
}
public static void main(String[] args)
{
Scanner S=new Scanner(System.in);
n=S.nextInt(); m=S.nextInt();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=S.nextInt();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=Math.max(ans,dfs(i,j));
System.out.println(ans+1);
}
}
T3
トピックの主なアイデア:固定形式、ルートノードのポイント加重バイナリツリーを前提として、下降のみ可能なxorパスの最大値を見つけます(xorパスの重みは、パス上のすべてのノードの排他的OR値です)。
n <= 1 e 5 n <= 1e5ん<=1 e 5
間違いは無数にあります...
(事前知識)
まず、「長さnのシーケンスで、2つの数値を選択してxorを最大化する」という質問を検討してください。
この問題は01trieで解決できます。Baiduで学習できます...
次に、この問題では、最初に前処理を検討します。w[x] w [x]w [ x ]は、xからルートノードへのパスのxor値です。次に、下りのみ可能なパスのxor値は、w [x] ^(w [すべての親ノード])の最大値に変換されます。
この部分は、次の疑似コードで表すことができます。
void dfs(int u)
{
trie插入当前值;
trie查询当前的xor最大值
dfs(儿子节点);
trie删除当前值;
}
対象の要件を完了することができます。
(弱い皿のブロガーの突然の精神遅滞のために...削除するトライを書く方法を忘れました...永続的な01トライを書いてください...最後に、デバッグできませんでした...
upd:
Tucao:どうしてみんなO(n 2)O(n ^ 2)O (n2)解雇されました...強く非難されました...どのようなデータですか?質問を書く際に作者は暴力を考慮していません...強く非難します!!!チェーンを作るだけで行き詰まる場合があります...このデータは修飾されていません