zoukankan      html  css  js  c++  java
  • 3.11 考试总结

    String

    题意

    • 给你一个01串S,q次询问,每次询问一个01串T,先对T复制到长度与S相同为止,再回答从当前的T至少操作多少次可以得到S,一次操作指取反一个区间的所有元素((sum|T|,|S|le2 imes10^5)).

    题解

    ​ 这种01串加取反操作肯定会想到异或运算,我们定义一个串的异或序列A满足(A_i=S_i extrm{ xor }S_{i-1}),如果我们再每个串的结尾再加上一个0,那么异或序列就和01串一一对应了,因为操作的是区间,所以每次就是取反异或序列的两个位置,那么我们就是寻找两个串上一共有多少对位置元素不同.

    ​ 我们先证明串的长度种类是不超过(sqrt{2 imes 10^5})的,这个应该挺显然,分小于根号大于根号的串讨论一下就好了.那么我们把询问串按长度分类统计就可以做到(O(|S|sqrt{sum|T|}))的复杂度了.

    代码

    #include <bits/stdc++.h>
    
    #define x first
    #define y second
    #define mp make_pair
    #define pb push_back
    #define For(i, a, b) for (int i = a; i <= b; ++ i)
    #define Forr(i, a, b) for (int i = a; i >= b; -- i)
    
    using namespace std;
    
    const int MAXN = 2e5;
    
    vector<pair<vector<int>, int>> Q[MAXN + 5];
    
    int S[MAXN + 5], ans[MAXN + 5], vis[2][MAXN + 5], n, m, q;
    
    int main()
    {
    	static char s[MAXN + 5];
    	scanf("%s%d", s + 1, &q), n = strlen(s + 1);
    	For(i, 1, n) S[i] = s[i] == 'a';
    	Forr(i, n + 1, 1) S[i] ^= S[i - 1];
    	For(i, 1, q)
    	{
    		scanf("%s", s + 1);
    		m = min((int)strlen(s + 1), n);
    		vector<int> vec = {0};
    		For(j, 1, m) vec.pb(s[j] == 'a');
    		vec[0] = vec[m];
    		Q[m].pb(mp(vec, i));
    	}
    	For(len, 1, n) if (!Q[len].empty())
    	{
    		int ed = (n - 1) % len + 1;
    		For(i, 2, n) ++ vis[S[i]][(i - 1) % len + 1];
    		for (auto v : Q[len])
    		{
    			ans[v.y] = (S[1] ^ v.x[1]) + (S[n + 1] ^ v.x[ed]);
    			For(i, 1, len) ans[v.y] += vis[v.x[i] ^ v.x[i - 1] ^ 1][i];
    		}
    		For(i, 1, len) vis[0][i] = vis[1][i] = 0;
    	}
    	For(i, 1, q) printf("%d
    ", ans[i] >> 1);
    	return 0;
    }
    

    Sea

    题意

    • 给你一个DAG,每个点有点权,你需要保证任何时候你经过的点的点权和不超过(H),在此基础上每次随机选择一条边走,如果无路可走就会清空经过的点权并回到(1)号点,求(1)号点到(n)号点的期望步数.((n,Hle100)

    题解

    ​ 如果没有回到一号点的边直接期望DP就好了,有的话我们发现每个点只是多了一条出边,倘若我们知道(1)号点到(n)号点的期望步数还是可以期望DP,那么我们二分答案后用算出来的期望步数调整二分的答案就好了.

    代码

    #include <bits/stdc++.h>
    
    #define For(i, a, b) for (int i = a; i <= b; ++ i)
    #define Forr(i, a, b) for (int i = a; i >= b; -- i)
    
    using namespace std;
    
    const int N = 100;
    const long double eps = 1e-9;
    
    vector<int> G[N + 5];
    
    int a[N + 5], mx[N + 5];
    int n, H;
    
    bool check(long double e)
    {
    	static long double dp[N + 5][N + 5];
    	For(i, 1, n) For(j, 1, H) dp[i][j] = 1e9;
    	For(i, 1, H) dp[n][i] = 0;
    	Forr(u, n - 1, 1) For(j, mx[u] + 1, H) if (!G[u].empty())
    	{
    		long double res = 0;
    		for (auto v : G[u]) res += min(dp[v][j - a[v]], H - (j - a[v]) + e);
    		dp[u][j] = res / ((int)G[u].size()) + 1;
    	}
    	return dp[1][H] < e;
    }
    
    int main()
    {
    	int x, y, m;
    	scanf("%d%d%d", &n, &m, &H);
    	For(i, 1, m)
    	{
    		scanf("%d%d", &x, &y);
    		G[x].push_back(y);
    	}
    	For(i, 1, n) scanf("%d", &a[i]);
    	For(u, 1, n) for (auto v : G[u])
    		mx[u] = max(mx[u], a[v]);
    	long double l = 0, r = 2e6;
    	while (l + eps < r)
    	{
    		long double mid = (l + r) / 2;
    		if (check(mid)) r = mid;
    		else l = mid;
    	}
    	if (l >= 1e6) puts("-1");
    	else printf("%.6Lf", l);
    	return 0;
    }
    
    

    Sword

    题意

    • (sumlimits_{i = 1}^nR^ii^k)(10^9+7)取模的结果(,(kle5000,R,nle10^{16},R ext{ mod }10^9+7 eq1))

    题解

    ​ 设那个式子为(f(k)),我们错位相减一下可以得到:

    [f(k)=frac{R^{n+1}n^k-sum_{i = 1}^nR^i(i^k-(i-1)^k)}{R-1} ]

    ​ 把( m k=1,2,3)代入进去找下规律就可以发现:

    [f(k)=frac{R^{n+1}n^k-sum_{j = 1}^k(-1)^jf(k-j)inom k j}{R-1} ]

    ​ 记忆化搜索即可,复杂度(O(k^2)) .(证明以后有时间再补)

    代码

    #include <bits/stdc++.h>
    
    #define x first
    #define y second
    #define pb push_back
    #define mp make_pair
    #define inf (0x3f3f3f3f)
    #define SZ(x) ((int)x.size())
    #define ALL(x) x.begin(), x.end()
    #define Set(a, b) memset(a, b, sizeof(a))
    #define Cpy(a, b) memcpy(a, b, sizeof(a))
    #define DEBUG(...) fprllf(stderr, __VA_ARGS__)
    #define debug(x) cout << #x << " = " << x << endl
    #define Rep(i, a) for (int i = 0, i##end = (a); i < i##end; ++ i)
    #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
    #define Forr(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
    #define Travel(i, u) for (int i = head[u], v = to[i]; i; v = to[i = nxt[i]])
    
    namespace IO { 
    
    	const int N = 1e6;
    
    	static char s[N], *S = s, *T = s, t[N], *E = t;
    
    	inline void flush() { fwrite(t, 1, E - t, stdout), E = t; }
    
    	inline char getc() {
    		if (S == T) T = (S = s) + fread(s, 1, N, stdin);
    		return S == T ? 0 : *S ++;
    	}
    
    	inline void putc(char c) {
    		if (E == t + N - 1) flush();
    		*E ++ = c;
    	}
    }
    
    using IO::getc;
    using IO::putc;
    using IO::flush;
    using namespace std;
    using ll = long long;
    using PII = pair <int, int>;
    
    template <class T>
    inline T read() {
    	T ___ = 1, __ = getc(), _ = 0;
    	for (; !isdigit(__); __ = getc())
    		if (__ == '-') ___ = -1;
    	for (; isdigit(__); __ = getc())
    		_ = _ * 10 + __ - 48;
    	return _ * ___;
    }
    
    template <class T>
    inline void write(T _, char __ = '
    ') {
    	if (!_) putc(48);
    	if (_ < 0) putc('-'), _ = -_;
    	static int sta[111], tp;
    	for (sta[tp = 0] = __; _; _ /= 10)
    		sta[++ tp] = _ % 10 + 48;
    	while (~tp) putc(sta[tp --]);
    }
    
    template <class T>
    inline bool chkmax(T &_, T __) {
    	return _ < __ ? _ = __, 1 : 0;
    }
    
    template <class T>
    inline bool chkmin(T &_, T __) {
    	return _ > __ ? _ = __, 1 : 0;
    }
    
    inline void proStatus() {
    	ifstream t("/proc/self/status");
    	cerr << string(istreambuf_iterator <char> (t), istreambuf_iterator <char> ());
    }
    
    const int mod = 1e9 + 7;
    const int N = 5000;
    
    ll fac[N + 5], ifac[N + 5];
    
    ll n, R, K;
    
    inline ll qpow(ll a, ll x) { 
    	ll ret = 1; 
    	a %= mod, x %= (mod - 1);
    	while (x) {
    		if (x & 1) (ret *= a) %= mod;
    		x >>= 1, (a *= a) %= mod;
    	}
    	return ret;
    }
    
    inline ll C(ll x, ll y) { 
    	return fac[x] * ifac[y] % mod * ifac[x - y] % mod;
    }
    
    ll f[N + 5], val, mom, poww[N + 5];
    
    ll query(ll k) { 
    	if (f[k]) return f[k];
    	if (!k) return f[k] = (val - R % mod + mod) * mom % mod;
    	ll res = val * poww[k] % mod;
    	For(j, 1, k) (res += (j & 1 ? -1 : 1) * (query(k - j) * C(k, j) % mod)) %= mod;
    	return f[k] = (res + mod) * mom % mod;
    }
    
    signed main() {
    
    	fac[0] = 1; 
    	For(i, 1, N) fac[i] = fac[i - 1] * i % mod;
    	ifac[N] = qpow(fac[N], mod - 2);
    	Forr(i, N, 1) ifac[i - 1] = ifac[i] * i % mod;
    
    	for (ll T = read<ll>(); T -- ; ) {
    		K = read<ll>(), n = read<ll>(), R = read<ll>();
    		val = qpow(R, n + 1), mom = qpow(R - 1, mod - 2);
    		poww[0] = 1; 
    		For(i, 1, K) poww[i] = poww[i - 1] * (n % mod) % mod;
    		Set(f, 0), printf("%lld
    ", query(K));
    	}
    
    	return flush(), 0;
    }
    

    总结

    ​ 今天考的不算好但是总算有进步了,需要努力的地方还是对题目性质的挖掘,然后应该善于发现规律???

  • 相关阅读:
    改变传统电视对客厅文化的影响
    移动终端三分天下 何与争峰
    全球移动IM应用的迅猛发展前景
    电子医疗的发展和实现
    poj 1523(无向图求割点)
    poj 3255(次短路)
    poj 2125
    poj 3204
    图的连通度问题的求法(转)
    poj 3308
  • 原文地址:https://www.cnblogs.com/brunch/p/10512909.html
Copyright © 2011-2022 走看看