A
题目链接:http://www.ifrog.cc/acm/problem/1111
分析:容易发现本题就是排序不等式, 将A数组与B数组分别排序之后, 答案即N∑i=1Ai×Bi
此题有坑,反正据我提交而言,一直RE,之后发现两个地方会出错,一是定义数组要放在main函数之前,第二是ans+=1LL*a[i]*b[i],如果少了1LL,结果肯定WA,这就是此题的亮点所在!
1 #include <bits/stdc++.h> 2 3 using namespace std ; 4 5 typedef long long LL ; 6 7 const int MAXN = 500010 ; 8 9 int n ; 10 11 int a[MAXN], b[MAXN] ; 12 13 int main() { 14 scanf("%d", &n) ; 15 for (int i = 1; i <= n; i ++) scanf("%d", &a[i]) ; 16 for (int i = 1; i <= n; i ++) scanf("%d", &b[i]) ; 17 sort(a + 1, a + n + 1) ; 18 sort(b + 1, b + n + 1) ; 19 LL ans = 0 ; 20 for (int i = 1; i <= n; i ++) ans += 1LL * a[i] * b[i] ; 21 cout << ans << endl ; 22 }
B
题目链接:http://www.ifrog.cc/acm/problem/1112
分析:
一个显然的想法是每一次二分加入到第几个数的时候, 混乱度超过M, 然后暴力检验, 复杂度显然可以是O(N2logN)
级别
我们可以换一种二分方式
令当前左端点为L
, 我们先找到一个最小的K, 使得[L,L+2K)这个区间混乱度超过M
然后右端点在[L+2K−1,L+2K)
中二分即可
考虑每删去至少2K−1
个数, 所需要的时间复杂度最大为O(2KKlogN)
故总复杂度为O(Nlog2N)
1 #include <bits/stdc++.h> 2 3 using namespace std ; 4 5 int n ; 6 7 typedef long long LL ; 8 9 LL M ; 10 11 const int MAXN = 300010 ; 12 13 int a[MAXN] ; 14 15 int ps[MAXN], p[MAXN], cnt[MAXN], v[MAXN]; 16 bool vis[MAXN] ; 17 18 19 bool check(int l, int r) { 20 for (int i = l; i <= r; i ++) p[i] = a[i] ; 21 sort(p + l, p + r + 1) ; 22 LL ans = 0 ; 23 for (int i = l; i <= r; i ++) { 24 ans += 1LL * p[i] * v[i - l + 1] ; 25 } 26 return ans <= M ; 27 } 28 29 int main() { 30 cin >> n >> M ; 31 for (int i = 1; i <= n; i ++) scanf("%d", &a[i]) ; 32 for (int i = 1; i <= n; i ++) scanf("%d", &v[i]) ; 33 int l = 1, r = 1 ; 34 for (; l <= n;) { 35 int last = 1, lastp = r - 1 ; 36 for (; check(l, r) && lastp < r; lastp = r , r = min(n, r + last), last <<= 1) ; 37 if (lastp == r) break ; 38 int lp = lastp + 1, rp = r ; 39 while (lp < rp) { 40 int mid = ((lp + rp) >> 1) ; 41 if (!check(l, mid)) rp = mid ; 42 else lp = mid + 1; 43 } 44 cnt[lp] ++ ; 45 l = lp + 1, r = l ; 46 } 47 for (int i = 1; i <= n; i ++) { 48 cnt[i] += cnt[i - 1] ; 49 printf("%d", cnt[i]) ; 50 if (i < n) putchar(' ') ; 51 } 52 putchar(10) ; 53 }
C
题目链接:http://www.ifrog.cc/acm/problem/1113
分析:
注意到, K条路径两两相交的充要条件是这K
条路径有一段公共路径。
对于一条路径, 点数-边数恒为1
所以我们可以算出所有可能的情况中, K
条路径的公共点的个数 减去K
条路径的公共边的条数, 即为答案
我们可以枚举每一个点以及每一条边的贡献, 对于一个点来说, 它的贡献就是所有经过它的路径条数的K
次方,边同理
复杂度O(NlogK)
, 瓶颈在于快速幂
1 #include <bits/stdc++.h> 2 3 #define MOD 1000000007 4 5 #ifdef WIN32 6 #define LLD "%I64d" 7 #else 8 #define LLD "%lld" 9 #endif 10 11 using namespace std ; 12 13 int n, K ; 14 15 typedef long long LL ; 16 17 int qpow(int a, int b) { 18 int ret = 1 ; 19 for (; b; b >>= 1, a = 1LL * a * a % MOD) if (b & 1) ret = 1LL * ret * a % MOD ; 20 return ret ; 21 } 22 23 const int MAXN = 500010 ; 24 25 int siz[MAXN], fa[MAXN]; 26 27 vector<int> g[MAXN]; 28 29 int main() { 30 scanf("%d%d", &n, &K) ; 31 for (int i = 2; i <= n; i ++) scanf("%d", &fa[i]) ; 32 for (int i = n; i; i --) { 33 siz[i] ++ ; 34 siz[fa[i]] += siz[i] ; 35 g[fa[i]].push_back(i) ; 36 } 37 int ans = 0 ; 38 for (int i = 2; i <= n; i ++) { 39 int t = 1LL * siz[i] * (n - siz[i]) % MOD ; 40 ans = (ans - qpow(t, K) + MOD) % MOD ; 41 } 42 for (int i = 1; i <= n; i ++) { 43 int t = 0 ; 44 for (int j = 0; j < g[i].size(); j ++) { 45 t += 1LL * siz[g[i][j]] * (n - siz[g[i][j]] - 1) % MOD ; 46 t %= MOD ; 47 } 48 t += 1LL * (siz[i] - 1) * (n - siz[i]) % MOD ; 49 t %= MOD; 50 t = 1LL * t * ((MOD + 1) / 2) % MOD ; 51 t += n ; 52 t %= MOD ; 53 ans += qpow(t, K) ; 54 ans %= MOD ; 55 } 56 printf("%d\n", ans) ; 57 }
D
题目链接:http://www.ifrog.cc/acm/problem/1114
分析:
记SMN 为左边N个点, 右边M
个点的完全二分图生成树个数
答案即SKN−K×(N−1K−1)
, 证明显然, 因为把树上的点按照奇偶分层,即得到一个二分图, 每一棵树都对应了这个完全二分图的一个生成树
SMN=NM−1×MN−1
, 暴力用Matrix−Tree可以消元得到这个结论。
1 #include <bits/stdc++.h> 2 3 #define MOD 998244353 4 5 using namespace std ; 6 7 int n, k; 8 9 int qpow(int a, int b) { 10 int ret = 1; 11 for (; b; b >>= 1, a = 1LL * a * a % MOD) if (b & 1) ret = 1LL * ret * a % MOD ; 12 return ret ; 13 } 14 15 int C(int n, int m) { 16 int ans = 1 ; 17 for (int i = 1; i <= m; i ++) { 18 ans = 1LL * ans * (n - i + 1) % MOD * qpow(i, MOD - 2) % MOD ; 19 } 20 return ans ; 21 } 22 23 int main() { 24 25 scanf("%d%d", &n, &k) ; 26 n -= k ; 27 int ans = 1LL * qpow(n, k - 1) * qpow(k, n - 1) % MOD ; 28 ans = 1LL * ans * C(n + k - 1, k - 1) % MOD ; 29 printf("%d\n", ans) ; 30 }
E
题目链接:http://www.ifrog.cc/acm/problem/1115
分析:
1 #define OPENSTACK 2 3 #include <bits/stdc++.h> 4 #define MAXN 100010 5 #define Q 322 6 #define INF ~0ULL 7 8 using namespace std; 9 10 int n , m , cnt , a[ MAXN ] , tag[ MAXN ] , caocoacao[ MAXN ] , up[ MAXN ] , vis[ MAXN ]; 11 int gandan [ MAXN ] , fa[ MAXN ] , size[ MAXN ] , son[ MAXN ] , xxxxxx[ MAXN ]; 12 unsigned char left_bit[65536] , ssssssss[65536]; 13 unsigned int wocaonimabis[31][ MAXN ] , f[31][65536] , lastans; 14 15 struct wocaonima 16 { 17 unsigned long long bit[470]; 18 void clear() 19 { 20 memset( bit , 0 , sizeof( bit ) ); 21 } 22 void operator |= ( const wocaonima & rhs ) 23 { 24 for( register int i = 0 ; i <= 469 ; i++ ) 25 bit[i] |= rhs.bit[i]; 26 } 27 void operator |= (const int x) 28 { 29 bit[x >> 6] |= 1ll << ( x & 63 ); 30 } 31 inline int find( unsigned char k ) 32 { 33 int len = 0 , v[4]; 34 register unsigned int x = 0; 35 for( register int i = 0 ; i <= 469 ; i++ ) 36 { 37 v[0] = bit[i] & 65535 , v[1] = ( bit[i] >> 16 ) & 65535 , v[2] = ( bit[i] >> 32 ) & 65535 , v[3] = ( bit[i] >> 48 ); 38 for( register char j = 0 ; j <= 3 ; j++ ) 39 if( v[j] == 65535 ) len += 16; 40 else 41 { 42 //if( len + left_bit[ v[j] ] ) cerr << " " << len + left_bit[ v[j] ] << endl; 43 x += wocaonimabis[k][ len + left_bit[ v[j] ] ]; 44 x += f[k][ v[j] ]; 45 len = ssssssss[ v[j] ]; 46 } 47 } 48 return x; 49 } 50 } ans; 51 52 wocaonima BIT[Q + 5][Q + 5]; 53 vector < int > linker[ MAXN ]; 54 55 #define cur linker[x][i] 56 57 void dfs1( int x ) 58 { 59 size[x] = 1; 60 for( int i = 0 ; i < linker[x].size() ; i++ ) 61 if( cur != fa[x] ) 62 { 63 fa[ cur ] = x , gandan [ cur ] = gandan [x] + 1; 64 dfs1( cur ) , size[x] += size[ cur ]; 65 if( size[ cur ] > size[ son[x] ] ) son[x] = cur; 66 } 67 } 68 69 void dfs2( int x , int t ) 70 { 71 xxxxxx[x] = t; 72 if( son[x] ) dfs2( son[x] , t ); 73 for( int i = 0 ; i < linker[x].size() ; i++ ) 74 if( cur != fa[x] && cur != son[x] ) 75 dfs2( cur , cur ); 76 } 77 78 inline int lca( int a , int b ) 79 { 80 while( xxxxxx[a] != xxxxxx[b] ) 81 { 82 if( gandan [ xxxxxx[a] ] < gandan [ xxxxxx[b] ] ) swap( a , b ); 83 a = fa[ xxxxxx[a] ]; 84 } 85 return gandan [a] < gandan [b] ? a : b; 86 } 87 88 #undef cur 89 90 struct io 91 { 92 char ibuf[1 << 23] , * s , obuf[1 << 20] , * t; 93 int a[24]; 94 io() : t( obuf ) 95 { 96 fread( s = ibuf , 1 , 1 << 23 , stdin ); 97 } 98 ~io() 99 { 100 fwrite( obuf , 1 , t - obuf , stdout ); 101 } 102 inline int read() 103 { 104 register int u = 0; 105 while( * s < 48 ) s++; 106 while( * s > 32 ) 107 u = u * 10 + * s++ - 48; 108 return u; 109 } 110 template < class T > 111 inline void print( T u , int v ) 112 { 113 print( u ); 114 * t++ = v; 115 } 116 template< class T > 117 inline void print( register T u ) 118 { 119 static int * q = a; 120 if( !u ) * t++ = 48; 121 else 122 { 123 if( u < 0 ) 124 * t++ = 45 , u *= -1; 125 while( u ) * q++ = u % 10 + 48 , u /= 10; 126 while( q != a ) 127 * t++ = * --q; 128 } 129 } 130 } ip; 131 132 #define read ip.read 133 #define print ip.print 134 135 inline void addedge( int x , int y ) 136 { 137 linker[x].push_back( y ); 138 linker[y].push_back( x ); 139 } 140 141 int main() 142 { 143 #ifdef OPENSTACK 144 int size = 64 << 20; // 64MB 145 char *p = (char*)malloc(size) + size; 146 #if (defined _WIN64) or (defined __unix) 147 __asm__("movq %0, %%rsp\n" :: "r"(p)); 148 #else 149 __asm__("movl %0, %%esp\n" :: "r"(p)); 150 #endif 151 #endif 152 srand( time( 0 ) ); 153 for( int s = 0 ; s < 65536 ; s++ ) 154 { 155 left_bit[s] = ssssssss[s] = 16; 156 for( register int i = 0 ; i < 16 ; i++ ) 157 if( !( ( s >> i ) & 1 ) ) 158 { 159 left_bit[s] = i; 160 break; 161 } 162 for( register int i = 15 ; ~i ; i-- ) 163 if( !( ( s >> i ) & 1 ) ) 164 { 165 ssssssss[s] = 15 - i; 166 break; 167 } 168 } 169 n = read() , m = read(); 170 for( int i = 0 ; i <= n ; i++ ) 171 for( register int j = wocaonimabis[0][i] = 1 ; j <= 30 ; j++ ) 172 wocaonimabis[0][0] = 0 , wocaonimabis[j][i] = wocaonimabis[j - 1][i] * i; 173 for( int j = 0 ; j <= 30 ; j++ ) 174 for( int s = 0 ; s < 65536 ; s++ ) 175 { 176 int len = 0; 177 for( register int i = left_bit[s] + 1 ; i <= 15 - ssssssss[s] ; i++ ) 178 if( ( s >> i ) & 1 ) len++; 179 else f[j][s] += wocaonimabis[j][ len ] , len = 0; 180 if( len ) f[j][s] += wocaonimabis[j][ len ]; 181 } 182 for( register int i = 1 ; i <= n ; i++ ) a[i] = read(); 183 for( register int i = 1 ; i < n ; i++ ) addedge( read() , read() ); 184 dfs1( 1 ) , dfs2( 1 , 1 ); 185 for( int i = 1 ; i <= min( n , Q ) ; i++ ) 186 { 187 int pos; 188 while( vis[ pos = rand() * rand() % n + 1 ] ); 189 vis[ pos ] = 1 , tag[i] = pos , caocoacao[ tag[i] ] = i; 190 } 191 for( int i = 1 ; i <= min( n , Q ) ; i++ ) 192 { 193 int cur = tag[i]; 194 ans.clear(); 195 do 196 { 197 ans |= a[ cur ]; 198 if( cur != tag[i] && caocoacao[cur] ) 199 { 200 BIT[i][ caocoacao[ cur ] ] |= ans; 201 if( !up[ tag[i] ] ) 202 up[ tag[i] ] = cur; 203 } 204 cur = fa[ cur ]; 205 } 206 while( cur ); 207 } 208 for( int i = 1 ; i <= m ; i++ ) 209 { 210 int cnt = read(); 211 ans.clear(); 212 for( int j = 1 ; j <= cnt ; j++ ) 213 { 214 int x = read() ^ lastans , y = read() ^ lastans , z = lca( x , y ); 215 ans |= a[z]; 216 while( !caocoacao[x] && x != z ) 217 { 218 ans |= a[x]; 219 x = fa[x]; 220 } 221 int now = x; 222 while( gandan [ up[x] ] > gandan [z] ) x = up[x]; 223 ans |= BIT[ caocoacao[ now ] ][ caocoacao[x] ]; 224 while( x != z ) 225 { 226 ans |= a[x]; 227 x = fa[x]; 228 } 229 while( !caocoacao[y] && y != z ) 230 { 231 ans |= a[y]; 232 y = fa[y]; 233 } 234 now = y; 235 while( gandan [ up[y] ] > gandan [z] ) y = up[y]; 236 ans |= BIT[ caocoacao[ now ] ][ caocoacao[y] ]; 237 while( y != z ) 238 { 239 ans |= a[y]; 240 y = fa[y]; 241 } 242 } 243 print( lastans = ans.find( read() ) , '\n' ); 244 } 245 #ifdef OPENSTACK 246 exit(0); 247 #else 248 return 0; 249 #endif 250 return 0; 251 }