HDU 6273 Master of GCD 【差分思想+快速冪】
阿新 • • 發佈:2018-12-17
思路:
記錄乘2次數最小的值和乘3次數最小的值再用快速冪求解這個大多數人都能想到,比較棘手的就是n和m都是10^5,如果某個區間一個個的遍歷去加1的話,會超時;這裡用到了差分思想;
假設對兩個區間操作 1 到 5 ,+1, 2 到 3, + 1,那麼有
1 0 0 0 0 -1 (1到5區間+1) , 1 1 0 -1 0 -1 (2到3區間+1) ;
我們從1開始依次做 a[i] += a[i-1] ; 可以發現遍歷一遍就能還原我們要的結果 1 2 2 1 1 0 ;這就是差分思想,即使n和m再大都無所畏懼;
//#include <ext/pb_ds/assoc_container.hpp> //#include <ext/pb_ds/tree_policy.hpp> #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<queue> #include<map> #include<stack> #include<sstream> #include<vector> #include<string> #include<set> using namespace std; //using namespace __gnu_pbds; //------------------ 巨集定義 -------------------------------- #define IOS ios::sync_with_stdio(false); cin.tie(0); #define REP(i,n) for(int i=0;i<n;++i) //------------------- 預備函式 ------------------------------ int read(){ int r=0,f=1;char p=getchar(); while(p>'9'||p<'0'){if(p=='-')f=-1;p=getchar();} while(p>='0'&&p<='9'){r=r*10+p-48;p=getchar();}return r*f; } int dcmp (double x, double y) { if (fabs(x-y) < 1e-6) return 0; if (x > y) return 1; return -1; } //------------------- 常量+宣告 ------------------------------------------ //typedef tree<pair<long long,int>,null_type,less< pair<long long,int> >,rb_tree_tag,tree_order_statistics_node_update> rbtree; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<long long,long long> pll; const int Maxn = 1e5+10; const long long LINF = 1e18; const int INF = 0x3f3f3f3f; const int Mod = 998244353; const double PI = acos(-1.0); const double eps = 1e-6; //------------------------------------------------------------------------- ll two[Maxn], three[Maxn]; int pow_mod (int a, ll n) { if (n == 0) return 1; int x = pow_mod (a, n/2); ll ans = (ll)x*x % Mod; if (n & 1) ans = ans*a % Mod; return (int)ans; } int main (void) { int t, n, m; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n, &m); memset (two, 0, sizeof (two)); memset (three, 0, sizeof (three)); int L, R, x; for (int i = 0; i < m; ++i) { scanf ("%d%d%d", &L, &R, &x); if (x == 2) { two[L]++; two[R+1]--; } else { three[L]++; three[R+1]--; } } ll m1 = two[1], m2 = three[1]; for (int i = 2; i <= n; ++i) { two[i] += two[i-1]; three[i] += three[i-1]; m1 = min (m1, two[i]); m2 = min (m2, three[i]); } int ans = pow_mod (2, m1); ans = (ll)ans * pow_mod (3, m2) % Mod; printf ("%d\n", ans); } return 0; }