題意:
題解:
我們觀察一下它打字的過程,輸入乙個字元/回退一格,這不就是建立trie的過程嗎?
根據題意我們可以建出乙個trie,然後可以知道trie上哪個節點代表第幾個列印的字串。
那麼考慮如何求答案,這是乙個字串匹配,而且還有trie,所以我們可以建立乙個ac自動機。
如果有乙個問題(x,y),那麼我們只需要在ac自動機(trie)從上往下沿著字串y走,每走一步,就判斷一下這個節點如果一直跳fail是不是能夠到達x這個節點,如果是就答案加一。換句話說,每走一步,判斷一下這個節點在fail樹上是不是x的子節點即可。
那麼我們先將問題離線了並建出fail樹,然後將每個詢問(x,y)掛到y所在的節點上去。接著遍歷ac自動機(trie),每走乙個節點就在樹狀陣列上加一,遇到乙個有詢問的節點,就在樹狀陣列上查詢一下它的子樹即可。
#include#include#include
#include
#include
#include
using
namespace
std;
int n,m,df,num[100002],dfn[100002],zjds[100002],cnt,f[100002],ans[100002
];char s[100002
];typedef
struct
p;typedef
struct
pp;p p[
100002
];vector
g[100002
];vector
q[100002
];void
trie()
now=p[now].nex[s[i]-'a'
]; }
}void
bfs()
w=p[u].fall;
while(w && !p[w].nex[i])w=p[w].fall;
if (p[w].nex[i])p[p[u].nex[i]].fall=p[w].nex[i];
q.push(p[u].nex[i]);}}
for (int i=1;i<=cnt;i++)
g[p[i].fall].push_back(i);
}void dfs(intx)}
void gengxin(int x,int
y)int chaxun(int
x)void
xunwen()
else
if (s[i]=='b')
else
}int
main()
bfs();dfs(0);
xunwen();
for (int i=1;i<=m;i++)
printf(
"%d\n
",ans[i]);
return0;
}
貪心 阿狸和桃子的遊戲
顯然,這道題目的點權很容易去分配,其關鍵便在於邊權的處理上,即如何處理兩種邊權的情況。還有乙個問題在於,什麼叫做當前的最優選擇,點權和邊權的不同意味著有不同的選擇方法,這也讓這道題變得非常的棘手。我們便來思考一下,如何解決這兩個問題呢?那麼如何將邊權轉移到點權上呢?觀察到特殊的性質,我們發現題目僅僅...
阿狸和桃子的遊戲題解
每一道 簡單的黑題都有著詭異的思想,真不知道出題者怎麼想的。而這道題的重點在於把邊權轉換為點權,此題的方式是將邊權w平均分給被連線的兩點u和v。若u和v都被一人選擇,則他的分數較不加邊權前多了w 2 w 2 w,若被不同的人選擇,分數差多了 ans1 w 2 ans2 w 2 ans1 ans2 並...
NOI2011 JZOJ2784 阿狸的打字機
有乙個快取槽,設計乙個程式維護下面三個操作 i nser tc 在快取槽末尾插入小寫字元c pri nt 將快取所有字元連線輸出為字串 d elet e 刪除快取槽最後乙個字元 操作總共有 n 個。在所有操作結束之後,要支援 m個詢問。每個詢問都是查詢第 x 次輸出的字串在第 y次輸出的字串中出現了...